In all of the examples that we looked at, the way that the events were subscribed to was done manually,

meaning that you had to write some sort of a subscription code, whether it was a subscription to an

ordinary C-sharp event or it was some sort of more sophisticated mechanism, you had to write the code

to actually do this.

Now, what we are going to take a look at right now is a situation where all the subscriptions actually

happen automatically, meaning that you don’t explicitly subscribe a listener to some event.

Instead, you use a sort of convention based approach and there are different ways of actually doing

that.

You can have this approach done using attributes, but we’re going to be doing it using events and reflection

and an IOC container.

So this is going to be a fairly complicated example, but I’ll try to go through it slowly so that you

understand what’s going on.

So at the top level, I’m going to have an interface called an I event.

So this is just going to be an empty interface.

There’s nothing in it because we’re going to be basically just using it to describe the fact that some

components in the system send events to other components.

Now, in the kind of wider scale of things, you might have an event being actually only one of the

many different types.

You could also have commands, you could also have queries.

But we’re just going to stick with this event paradigm because that’s very simple.

So let’s suppose that we have some components that actually generate events.

So something happens in some of the components and what we can do is we can add additional interfaces.

For example, we can make an interface called I Send.

So we basically say that when when we declare a component, we say that this component sends a particular

event of type T event where T event is an I event.

So this is going to be our interface.

Now the interface for the sender actually has to have some sort of mechanism for actually sending events.

So here I’ll use the good old fashioned event keyword.

I’ll say that we have event handler of t event and we’ll call it sender.

Okay, so this is our interface for the components which are going to send messages and then we’ll have

a similar interface for the components which actually handle messages.

So they receive the messages and they get to process the messages.

So here we can say public interface, I handle t event.

So this is something that is actually going to get those events of a particular type where once again

t event is of type I event and we’re going to handle those.

So this is going to be fairly simple.

We’ll have a handle method and here I’ll have the same signature as we have in all of the trappings

when it comes to handling ordinary net events.

Meaning you have you have the sender as well as the T event args.

So these are the two interfaces.

And now what we can imagine is a situation where you have some components which actually generate some

sort of an event and then other components which need to handle this event and do something in relation

to it.

So for example, let’s, let’s imagine that we have a button that you can press one time.

So single click, but you can also double click it so we can have an event for this, so we can have

a class button pressed event, which is an I event like so and here I can say public int number number

of clicks.

So there’s a number of clicks that a button was pressed.

You can add additional information here like which of the mouse buttons was actually pressed like was

it the left one or the right one or the middle one.

It doesn’t really matter for our purposes.

So imagine now that you are working with some sort of UI.

So you have a class called button maybe and somebody clicks the button, maybe they click it once,

maybe they click it twice, whatever.

So this thing actually sends the button pressed event.

So we declare that we have this.

I send so we send a button pressed event.

Okay, so now we need to implement this interface among other things.

So I’m going to just go ahead and do this so you get the event.

But of course it would be really nice if we had some sort of utility method for actually invoking this

event So you can invoke it directly, but you can also do something like Public void Fire, where you

specify the number of clicks that somebody has clicked this particular button and then you get the sender,

you check that the sender is not null, so you use the null coalescing operator here.

Actually, no.

You use the the.

Okay, the question mark dot operator So you invoke, you invoke the event provided there are subscribers

on it.

And the first argument is this because the button is generating the event and the next argument is a

button pressed event, a button pressed event like so, except with the curly braces.

And here we can specify the number of clicks.

So the number of clicks is clicks.

That’s the argument to the method.

And we can.

Close all the braces and that’s pretty much it.

So we have our event generator.

And now let’s suppose that we just have a simple logging component.

So we’re not going to do anything complicated, just have a simple kind of console logger.

So public class logging, which I which is an I handle.

So this is something that handles the button pressed event.

Okay, so here we just go going to go ahead and implement this particular method.

So we have to put something in here.

I’m just going to do a console write line.

So here I’m going to say that the button was clicked and then specify the number of times the button

was clicked.

So args dot number of clicks times, that’s pretty much it.

So now here is the, the kind of the fun part.

We want to have the subscription declarative.

So as soon as somebody creates both a button as well as a login component, we want handle to be handling

this particular event and we want this to happen automatically without us having to write some sort

of my button dot sender plus equals my logging dot handle.

We don’t want to write this explicitly.

So the question is how can we do this?

Can we get this done automatically for us?

And in actual fact, we can.

In actual fact, what we can do is we can use a dependency injection container such as Autofac.

I’m going to be using Autofac in my case, and we can get the dependency injection container to perform

all the wirings automatically.

Now of course it’s going to involve reflection, but the performance cost isn’t really that great if

you are not creating these components too often.

So let’s take a look at how you would implement this.

This is going to be somewhat messy code.

So program public static, void main.

So let’s let’s start by setting up the container.

So I’m going to say var CV equals new container builder.

Now this is artifact specific stuff and you can check out the course on dependency injection that I’ve

got, which covers the whole Autofac story in quite a bit of detail, but I’m just going to use it here

and I’ll try to explain what’s going on.

So the container builder is basically the thing that allows you to configure the different dependencies

before they are built into an actual container that you can subsequently use in your program.

So what we’re going to be doing, I’ll just get the assembly quickly so I’ll say assembly dot, get

executing assembly.

So we’re going to need this later on.

Now the first thing we need to do is we need to register every component inside the dependency injection

container.

Now I’m going to start by registering the interfaces which publish something.

So what I’m going to do is I’m going to go through the assembly.

So I will use register assembly types.

This is the tool that actually goes through your entire assembly and finds all the different types of

a particular specification.

So I’m going to go through all the types in the assembly, so every single type and I will find all

the types of I send and this is done using as closed types of So because this is a generic, we’re going

to find all the types of I send of I send of basically anything.

So it’s an I send of some event or other that we’re going to be looking for.

And then what I’m going to do is I’m going to say that for every single one of these components, every

single one of these publishers, I’m going to make sure that we’re only going to have one instance.

So I’ll basically turn every single one of them into a singleton.

Now, the reason why I’m doing this is to simplify this demonstration, because if we allow multiple

instances of these, then it’s going to be a bit more complicated.

If they are all single instance, that means we know exactly which object to subscribe to.

Now, typically what you’d have is you’d have services depending on services, and many services are

a singleton by definition.

So this isn’t such a bad code, but we’ll talk about the issues that you’ll encounter if you don’t make

them singletons.

Okay.

So now here is the hard part.

Here is the part where we have to register all the types of I handled.

But that’s not enough.

It’s not enough for us to just register these types.

We also want to automatically subscribe them to the events of the corresponding I send types.

And this is going to be really complicated.

So let’s start somewhere.

So we’re going to register assembly types once again looking inside the assembly, but we are looking

for the types which are of type I handle.

Now here things are going to be a bit more complicated.

I’ll just write out this code so that you get to see what’s going on.

So this as close as close types right here.

We cannot use this unfortunately, as close types is going to basically go ahead and just find every

single I handle and that’s that’s pretty much it.

So we’re not just going to do that.

There’s going to be a lot more happening here.

So first of all, what I’m going to do is I’m going to take every single one of these types and I’ll

try to make sure that there is an interface in this type, which is of type I handle.

Now with these kind of open generics, it’s actually fairly complicated.

It’s fairly difficult to actually do this.

So let me show you how this works.

So what we’re going to do is we’re going to take the Type T, we’re going to get all the interfaces,

get interfaces, and then we’re going to say that.

We’re going to be looking.

So I’m going to be using the anti selector here.

We’re going to be looking for any interface which is of type I handle.

Now, the way you check this through reflection is you check that I is actually a generic type and you

check that the generic type definition is of type I handle.

So I dot get generic type definition is actually equal to type of.

I handle like this.

So fairly complicated stuff.

But we have to do this so there is no way for us to use as close types because unfortunately after this

where we also need to add additional information on top of that and it’s impossible for us to do that

with using as close types.

So we find all the I handles and what we need to do is we now need to go through the dependency injection

container.

And for every I handle of specific type, we need to find an I send of type T that has already been

registered in the container and we need to perform the actual subscription.

So how do we do this?

Well, in artifact this is possible by using on activated.

So on activated actually allows you to when the component has been created, but it hasn’t been returned

to the user yet.

You can customize it.

And that’s precisely the location where we’re going to perform the subscription.

So here I’ll take the the activated action and we’re going to have this big, huge chunk of code that’s

actually going to set up the subscription.

So how do we actually wire up the two pieces together?

Well, first of all, let’s actually let’s talk about where the instance is.

So if you look at act dot instance, that’s actually going to give you the instance that the dependency

injection container is about to give out to somebody.

So it’s about to give you this instance and this is the instance that you want to customize.

Now what do we want to happen here?

What we want to happen is if we have an instance which is an I handle of foo, what we need to do is

we need to go into the dependency injection container and we need to find every I send a foo and there

could be several components which actually implement this interface.

And for every single one of these components, we have to take this component and we have to basically

say dot sender plus equals.

And then we take this act dot instance and specify its own handle method as the handler to this, to

this event, basically.

So this is this sounds rather easy, but it’s actually going to be a bit complicated.

So the first thing I want to do is I want to actually grab the type of the instance because I have to

I know that I have some I handle of something, but I need this type t, I need this type foo because

that’s how I’m going to be looking for the senders.

So let’s grab the type.

So I’m going to say var instance type equals act dot instance, dot get type like so.

And I’m also going to grab the the interfaces of the actual instance type.

So I’m going to say var interfaces equals instance type gets interfaces.

So now I have all the interfaces that this type implements, but I know that I only care about, I handle

a foo, but remember every single one of these components can actually have multiple I handles.

So you could have a button which generates not just click events but also drag events.

So you have I send for a click and for drag and then you can have handlers for I handle click event,

I handle drag event, this sort of thing.

So we’re going to go through each of the interfaces.

So I’m going to say for var I in interfaces for each rather for each var I in interfaces and we’re going

to check whether or not this interface is actually of type I handle.

So this is a check similar to the check that we did here.

In actual fact, it’s an identical check.

So I’m going to say if I is generic type and I get generic type definition is actually equal to type

of I handle.

There we go.

So if this happens to be the case, then we are on to something and the first thing we need to do.

So now we know that we have an I handle of foo and we need to grab this foo somehow.

So how do we grab this foo?

Well, we get the generic argument.

So this is the generic argument.

We say var args zero equals I dot get generic arguments, we grab the generic arguments and we want

the argument at position zero.

Now we know it’s an I handle, so we know there is just a single argument there so it’s perfectly safe

to take the value at position zero here.

And then what we need to do is we need to find a corresponding I send a foo, but in order to find this,

we need to construct it first.

We need to, first of all, create the actual type.

So how do we do?

This.

Well, we say var sender type equals, and then we get type of I send an open generic and then we make

a generic type.

So we call make generic type and we provide the argument zero here.

So for a given I handle a foo.

We’re actually going to construct a type which is an eye center foo, which is going to be stored in

sender types.

Now what we need to do is we need to go into the dependency injection container and we need to find

every single I send off foo in the container.

So how do we do this?

Well, there is a trick to it.

You see, the dependency injection container can resolve an enumerable.

When you resolve an i enumerable of something, you find every instance of this I enumerable.

So if I tell the container, can you please give me an I enumerable of foo or specifically an I foo

is going to give me an every instance of every instance of an object which implements the I interface.

So how do we do this?

Well, first of all, we have to actually make this enumerable.

So we’re going to have a type because we need to construct this type.

We need to construct the i enumerable of I foo type.

That simply has to be done.

So we’re going to have var all sender types and here I’m going to take a type of I enumerable, enumerable

like so.

And then once again I’m going to say make generic type.

But this time around I provide the sender type.

So basically what I’m going to get is I’m going to get an type which is I enumerable of I send of whatever

foo we actually found.

So now that we have this I enumerable we can use it to find all the services which implement this.

I send a foo so I can say var all services equals act dot context.

So we get the context which allows us to actually perform operations on our container.

So here I can say resolve and I can resolve using this all sender types and that’s going to give us

every single type which implements an ice and a foo.

So now we can go through each of these services.

So I can say for each of our service in all services and I need to cast all services to an enumerable,

it’s not going to work otherwise.

So I cast everything to an enumerable.

And then what I want to do is I want to perform the actual event subscription.

So this is also going to take some time for us because the first thing we need to do is we need to get

reflection information for our event.

Now coming back up, if we just scroll up for a moment right here, you can see that the name of the

event that we actually use is called Sender.

So that’s the first thing that we need to do.

So for a given type I send of foo, we need to actually go ahead and we need to find the event called

sender.

So that’s the first thing we’re going to do.

We’re going to say var event info equals service dot get type dot get event called sender.

So now that we have this event, what we need to do is we need to find the other part.

And the other part is the handle method.

So remember the sender here.

This sender has to be wired up to this handle method.

They have to be connected together.

They are brothers in arms, so to speak.

So we need to find the reflection information for the handle method.

This is also rather easy.

Var handle method equals instance type get method called handle like so.

But now we need to connect them together.

And the way this is done, or one of the ways you can do this at least is to use a delegate dot, create

delegate.

So you basically need to create this event handler And the way this is done using reflection is as follows.

So I’m going to have a handler, which is going to be delegate, create, delegate.

So here you specify the event handler type.

So that’s event info, dot, event handler type.

We get this information from reflection.

I’m going to just put no in the second argument and then you specify the handle method like so.

So basically you are specifying how you’re going to handle particular events by creating this delegate,

but we haven’t added the actual event handler yet.

So here you say event info, dot add event handler.

You specify the service that we are connecting to and you specify the handler.

So things are now set up in the sense that we’ve set up this whole unactivated thing, which is going

to allow us to basically customize the component as it is being created.

So let’s do an additional trick here.

I’m going to say that this is going to be a singleton and I’m going to also register it as self.

Meaning that I register it not only as the interfaces specified, but also as the type itself in the

container.

So now that we’ve set all of this up, what we can do is we can actually start using the container.

We can use the container builder to build the actual container and then set up this, this interplay

between the button and the logging component.

So here I’m going to say var container equals build, and then I can make the button.

So var button equals container dot resolve button.

So this resolve operation isn’t particularly complicated because all it has to do is just, just give

us a singleton instance of a button.

But when I make the logging component, so container dot, resolve logging, this is where all the magic

happens.

This is where you’ll have an automatic subscription from the logging component to the button here.

So now that all of this is set up, I can say button dot fire, I can do it.

I can emulate a single click or I can emulate a double click.

So let’s actually run this.

Let’s take a look at what we kind of get here.

So as you can see, we’re getting the right output.

So we say Button clicked one times and button clicked two times.

So these output messages are actually coming out from the logging component, which has been automatically

subscribed to the events by the dependency injection container by our customization of the dependency

injection container.

Now even though this this approach that I showed you is really nice, there are a couple of shortcuts

that I’ve taken here.

And as you may have noticed, I’ve kind of cheated by making component single instance.

So now we get to kind of discuss some of the problems with this approach.

So there is there is a major problem with this approach in that the container doesn’t really track the

objects it creates because it doesn’t track the objects it creates.

You can have a problem where, let’s say after the container has been created, you register a sender

and all of the created I handle components aren’t going to be automatically subscribed to that sender.

So that’s problem number one.

That’s a fairly obvious problem because the container doesn’t know what handle object it has created

already.

It cannot go through those objects and automatically subscribe them to the new sender.

It’s simply not possible unless you somehow change your dependency injection container to actually track

every single object that it creates.

Now, in the case of singletons and the way the way that I’m cheating here is I’m using singletons.

In the case of singletons, that might be a bit easier because then you have just all of the objects

have effectively been created at at the startup of the application.

But when you don’t have singletons, that’s going to be a particular problem.

Another thing that hasn’t been shown here is Unsubscription.

So what happens when a component is no longer needed?

How do you how do you basically unsubscribe?

So we suddenly have some code here for adding the event handler, but I don’t see any code for removing

the event handler.

So this is something that is also fairly complicated to do because when it comes to implementing some

sort of disposable interface.

So let’s suppose that inside, let’s say the logging handler, you also want to implement Idisposable

like so for example.

So you, you implement, you implement the dispose method.

But the problem is that if you want to do this properly, then right inside this dispose method, you

have to call properties on the dependency injection container because effectively what happens here

is you have this handle method which is actually being used in a couple of subscriptions, maybe more

than one, and you want to find those subscriptions and basically unsubscribe.

But unfortunately, we don’t have any information about what you are subscribed to, especially with

the situation where Sanders can come in into the system after you’ve actually created the container.

So this is an additional problem.

This is an additional issue here.

Now, there are lots of other minor problems with with this approach, with this declarative approach.

So you might be wondering, well, what is the solution?

Is there a solution to this problem?

And in actual fact, the solution is to perhaps, perhaps you can keep the declarative approach.

But what you really want to do is you want to somehow centralize.

You want to have some sort of central registry for the subscriptions, meaning that instead of having

events in the senders and having some sort of handle method here, what you do is you actually use an

event broker.

So you use a centralized component where instead of events as such, you simply put messages on the

bus so you have some sort of centralized bus.

But then of course this introduces a dependency.

So this introduces this idea that you have some sort of central class, some sort of a central event

broker.

And then, of course, instead of instead of having the the event, sorry about that, instead of having

the events being generated using the.

Event keyword.

What you’d have is you’d have a constructor inside a constructor, you would take this event broker

and then you would maybe store it somewhere.

So you would say that you would have some sort of field.

I don’t like the underscores, actually.

You would you would have some sort of field here.

And then, of course, when it comes to firing, what you would do is you would take this broker and

you would say, you know, publish some sort of an event, publish some sort of an event somewhere here.

And then inside, let’s say the login component, you would the I handle would basically get you to

subscribe to a particular event on the broker, and that way you have better control.

So an event broker offers a much more, much more streamlined control of subscriptions because then

a subscription is a separate object.

And you can look at some of the examples like some of the examples in the mediator pattern for how you

can implement this basically event broker plus reactive extensions or a reactive extensions like mechanism

with disposable subscriptions basically solves this problem.

And yet you can still have your subscriptions being done in a declarative way using the IOC container.

But you are you’re in better control of how what happens when new objects enter the system, for example,

because in the classic sort of DCS approach, when an object is created, you might want to have an

event happen for that particular thing and you might want to log this event and that’s where you might

want to perform the actual subscriptions.

But I guess this is a discussion for another time.

So this is how you do declarative event subscriptions using, in our case, an IOC container.

Play Play Play Play Play Play Play Stop Start Play information alert