CompositeWPF: EventAggregator - when to use? - c#

I've been looking in to the Composite Application Library, and it's great, but I'm having trouble deciding when to use the EventAggregator... or rather - when NOT to use it.
Looking at the StockTraderRI example, I'm even more confused. They are using the EventAggregator in some cases, and "classic" events in other cases (in for example the IAccountPositionService interface).
I've already decided to use it for communication with a heavy work task, that should run on a background thread. In this case the EventAggregator offers marshalling of threads behind the scenes, so I don't have to worry much about that. Besides that I like the decoupling this approach offers.
So my question is: When I've started using the EventAggregator in my application, why not use it for all custom events?

This is a good question. In Composite WPF (Prism) there are 3 possible ways to communicate between parts of your app. One way is to use Commanding, which is used only to pass UI-triggered actions down the road to the actual code implementing that action. Another way is to use Shared Services, where multiple parts hold a reference to the same Service (Singleton) and they handle various events on that service in the classical way. For disconnected and asynchronous communication, as you already stated, the best way is to use the Event Aggregator (which follows closely Martin Fowler's pattern).
Now, when to and not to use it:
Use it when you need to communicate between modules. (for example, a Task module needs to be notified when a Task is created by any other module).
Use it when you have multiple possible receivers or sources of the same event. For example, you have a list of objects and you want to refresh it whenever an object of that type is saved or created. Instead of holding references to all open edit/create screens, you just subscribe to this specific event.
Don't use it when you only have to subscribe to normal events in the Model View Presenter area. For example, if your presenter listens to changes in the Model (for example the Model implements INotifyPropertyChanged) and your Presenter needs to react on such changes, it's better that your Presenter handles directly the PropertyChanged event of the Model instead of diverting such events through the Event Aggregator. So, if both the sender and receiver are in the same unit, there's no need to "broadcast" such events to the whole application.
I hope this answers your question.

Related

Using Events Delegates in multi tenant web application

I'm developing a multi tenant n-tier web application using asp.net Mvc 5.
In my service layer I am defining custom events for every important action and raising these events once these actions are executed. For example
Public event EventHandler EntityCreated;
Public void Create(Entity item) {
Save(item);
......
EntityCreated(this, item);
}
I intend on hooking up business rules and notifications to these events. The main reason I want to use events is decoupling of the logic and easy plug-ability of more events handlers without modifying my service layer.
Question:
Does it make sense using events and delegates in asp.net?
Most examples I find online are for win forms or wpf. I get the advantage when it comes to multithreaded applications. Also the events are defined once per form and are active for the lifetime of the form.
But in my case the events will be per http request. So is it an overhead defining these events?
As others pointed out that pub/sub or event bus is one solution. Another solution is something like what you are trying to do here but make it more formal.
Let's take a specific example of creating a customer. You want to send a welcome email when a new customer is created in the application. The domain should only be concerned with creating the customer and saving it in the db and not all the other details such as sending emails. So you add a CustomerCreated event. These types of events are called Domain Event as opposed to user interface events such as button click etc.
When the CustomerCreated event is raised, it should be handled somewhere in the code so that it can do the needful. You can use an EventHandlerService as you mentioned (but this can soon becomes concerned with too many events) or use the pattern that Udi Dahan talks about. I have successfully used Udi's method with many DI Containers and the beauty of the pattern is that your classes remain SRP compliant. You just have to implement a particular interface and registration code at the application bootstrap time using reflection.
If you need further help with this topic, let me know and I can share with you the code snippets to make it work.
I have implemented Udi Dahan's implementation as pointed out by #Imran but with a few changes.
My Events are being raised in a Service Layer and for that using a Static Class dint seem right. Also have added support for async/await.
Also going down the Events & Delegates path did work out but it just felt like an overhead to register the events per request.
I have blogged my solution here http://www.teknorix.com/event-driven-programming-in-asp-net

Should EventAggregator be used for point to point or broadcast messaging

I am using the EventAggregator in Caliburn.Micro in a Windows Phone 8 App.
There are a number of places where the view-models implement IHandle<SomeClass>.
My Question is since multiple classes will be handling when an object of SomeClass is published, even though they may not be the intended recipient. So what is the best way to deal with this....
Design message classes with different names (but essentially the same content) so that all communication between view-models is strictly point-to-point ?
Or put a source property in message classes so that all receivers know the source of the message so that it can be conditionally processed ?
There is no right or wrong answer to this question. As I see it:
There are cases when you want point-to-point and it is okay to have a specific message type (class) for solely this purpose
There are cases when you want an event like (broadcast) behavior
You can also have broadcast with active cancellation just like the one you have in System.Threading.Task, or like the one in the WPF eventing model where each handler is a visitor and can set the Handled flag of an event argument (say SomeClass) to true so that the other handler know they shouldn't be processing it anymore.
Also the name EventAggregator typically points to the fact that it's most common use is to aggregate handlers i.e. do broadcasting (at least this is how I see it)
Think about the WPF eventing model as an analogy.. You raise the event (publish it) but don't really care about how many handlers you have or what they are doing.

When should I use an event handler over an event aggregator?

When should I be using an Event Handler versus an Event Aggregator?
In my code, I have two ViewModels that controlled by a parent ViewModel, I am trying to decide if I should just use an event handler to talk between them? Or use an Event Aggregator? It is going to just be simple method call, I don't require parameters to be passed between them.
The way I see it, the EventAggregator is usually the heavy gun used when you want to publish an event to the entire application and more specifically - when you don't know who exactly is listening.
In your scenario that's not really the case, you have 2 view models that want to communicate, but they both know each other. So there is no real reason you can't use events.
I'll just mention that if you want to keep it a little more loosely-coupled - make an interface for each of the viewmodels that exposes the event. This way each VM will use the other VM's Interface instead of a specific instance.
Here is a link with some good info (that is alive as of 5/2019)...
https://learn.microsoft.com/en-us/previous-versions/windows/apps/xx130639(v%3dwin.10) (Microsoft, Prism)
The "Making key decisions" section describes when to use it.
Events in .NET implement the publish-subscribe pattern. The publisher and subscriber lifetimes are coupled by object references to each other, and the subscriber type must have a reference to the publisher type.
Event aggregation is a design pattern that enables communication between classes that are inconvenient to link by object and type references. This mechanism allows publishers and subscribers to communicate without having a reference to each other. Therefore, .NET events should be used for communication between components that already have object reference relationships (such as a control and the page that contains it), with event aggregation being used for communication between loosely coupled components (such as two separate page view models in an app). For more info see Event aggregation.
I crudely see this as suggesting C# events are good for layers (UI listening to bus logic) or parent/child (an instrument listening to its contained devices) and event aggregation is good for siblings (e.g., sibling UI panels or device to device communication).

EventAggregator Pattern: How To Pass Data?

I am looking at utilizing the Event Aggregator Pattern on a UI project I am working on (Silverlight/MVVM) to support loose coupling between views/viewmodels. We have written a few screens using a simple eventing system--it's not much more than a proof of concept at this point, but it does seem like a very elegent solution to creating a loosely coupled system.
The problem I am running up against is passing data from one ViewModel to another when the receiving ViewModel is not instantiated yet. For example, if a Customer List screen is open, a user might click a specific customer to open an edit/view Customer Detail screen (perhaps in a child window). The Customer Detail screen needs a customer (or customer Id) in order to function.
So is seems reasonable that the OpenCustomerDetailEvent would contain the relevant customer information, but what are some options for injecting that information into the Customer Detail V/VM? Since it's not in memory yet when the event is handled, it can't directly listen for the event (it can't itself be the handler). We are using a depenency injection container to create both the view and view model (we currently do "view first"), so having a separate handler inject the data via the constructor is not a great option.
What are some other options for getting the data into the View(Model) once it's constructed? An init method that takes strongly typed parameters? Using a setter to inject the data? Having the handler create the V/VM and then dispatch a second event that the VM listens for?
For this purpose i´m using the Prism Framework in my silverlight application. It provides an implementation of the EventAggregator pattern and a view navigation infrastructure.
In the case of prism, you will use NavigationParameters, that provide information for a view/viewmodel what data to use and to initialize. If the view/viewmodel isn´t created yet, the EventAggregator pattern is useless, cause it isn´t registered to the event yet.
If you want to rely on your own framework, i would take a look at the prism framework how view navigation is implemented there and to pick up some pieces for your own framework.
Personally i would encourage you, to use the prism framework.

Best pattern for change notification (events or delegates)

I have a solution where i pass a collection of items from a source to a presenter. When the source is updated I want to be able to notify the presenter to show the new result.
What comes to mind is to make a ChangeNotification class, pass it along with the result and have that class notify the presenter. Now as I see it this can be implemented in two ways, either ChangeNotification can have events that the presenter subscribes to, or it can have delegates that the presenter sets and the source calls if it is not null.
The benefits of using events is that more than consumer can react to the notification and you can hook up reactive extensions to it, the downside is that you have to manage subscribe/desubscribtion of the events for proper garbage collection. Delegates are simple but you lose some flexibility.
What is the most elegant pattern for situation like this? Is there some other way I haven't thought of?
If you will have multiple observers, Events or MultipleDelegates would be required. If you will only have one observer, and want to enforce that, a delegate would suffice. However, in terms of which is best, IMHO I would say the event is more flexible and lends itself very well to the pattern. The ObservableCollection and INotifyPropertyChanged are event based implementations. By the way, +1 to tbischel for the references to these classes.
There are two built in patterns for this scenerio.
First, you could implement the INotifyPropertyChanged interface. This is better if you want to notify the presenter of changes to properties of the objects themselves in the collection. (or the source object itself, if that is where changes occur).
The second is to pass your presenter an ObservableCollection containing your objects. This is better if you want to notify the presenter that an item has been added or removed from the collection. Both are event driven models that any subscriber could hook into.
Edit: The underlying pattern is the "Observer" pattern... you can roll out your own version if you want, you have the details down.
I agree with the other answers that INotifyPropertyChanged, INotifyCollectionChanged and other related interfaces are property the first place to turn but I wanted to add in third option which would be to implement the observer pattern. If your are not familiar with this pattern, it is how Java achieves it's event functionality through what are called event listeners. There is no reason why this pattern cannot be adopted in C# though and in some cases it may provide a more elegant solution than the use of events and delegate especially when there may be several coordinated events that are generally all subscribed to by an interested party.
Another option too is deriving from DependencyObject and implementing DependencyProperties in order to get the change notifications that are built-in and that are optimized for WPF. I tend not to go this route because I don't like the requirement of having a specific base class but there are some good arguments for why it is sometimes the right choice and in fact some MVVM frameworks even use it as the basis of change notifications for ViewModel classes too.

Categories