Prism Event Aggregators and WCF Services and Unity - c#

I am using prism event aggregators to trigger and associate events (publish and subscribe). The service is only instantiated if there is a request for it. Either from a client (through a channel) or from another service (as a class object).
Issue:
If an event is not subscribed (registration and instantiation) then even if it is published nothing
happens i.e no handler will be called.
Scenario:
If I am using lets say WCF services that act as our subscribers and also publishers and the service subsriber instance has not yet been created and the events get triggered,what can be done to handle this since as at this point the subscriber instance has not been created. (Registration has been done though).
Note: I am subscribing to events in the ctor of the service.
So , in short, I am looking to make sure all subscribers are instanstiated before the publish (event trigger call).
Possible Solution: I was looking at Unity application Block to resolve this dependency but wanted to find that if this is the right direction. For this purpose I was thinking of doing something like this in global.asax.cs application start method:
IUnityContainer container = new UnityContainer();
container.RegisterType<ISubscribeEvent ,EventSubsriber>();
and then I could
EventPublisher = container.Resolve<EventPublisher>();
where the ctor of EventPublisher class is
public EventPublisher(ISubscribeEvent obj)
{
}
where ISubscribeEvent will be an interface that every subscriber will implement. So that whenever an event is raised the class implementing ISubscribeEvent interface will be instantiated.
Does this approach make sense? Are there any alternatives?
EDIT:
The events would occur at the server and the subscribers would also be services on the server i.e the service to service call will not be going through the channel but as normal class call.
Update:
I have also looked at the IInstanceProvider here as it can provide an interface ,which can be used to control the instantiation of WCF service instances using Unity.WCF.

That won't work.
Event aggregators assume long-living objects, objects that first subscribe to events and then live long enough to get notifications.
WCF service instances are short-living objects. An instance is activated once the request begins and is deleted once the request completed.
The probability that your publisher and subscriber both live in the very same moment of time is low, as you have noticed, the subscriber is not yet created.
I believe your issue stems from the fact that you are misusing event aggregator there. A wcf service can publish events but there is no point in a wcf service being a subscriber registered in an event aggregator. A wcf service already is a subscriber - it can be called by other beings that "notify" it just by calling it.
If you want your services to "notify" other services, just call these other services as you'd normally call them.

Related

Are C# events feasible for domain events in DDD? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I read that people use event dispatching libraries for domain events in their domain-driven design.
The C# language have built-in support for events using the event keyword together with the EventHandler<> class. Is it feasible to use this instead of a event dispatcher library (such as MediatR)?
I know that domain events are often dispatched when persisted, not when the method on the aggregate is called. But by adding the events to a List<Action> you can defer the raising of events.
Event declaration:
public event EventHandler<InvoiceCreatedEventArgs> InvoiceCreated;
Deferred event raising:
private ICollection<Action> _events = new List<Action>();
public void AddDomainEvent(Action action)
{
_events.Add(action);
}
protected virtual void OnInvoiceCreated(InvoiceCreatedEventArgs e)
{
AddDomainEvent(() => { InvoiceCreated?.Invoke(this, e); });
}
If the events are exposed as public members of the root aggregate then the application would have to resubscribe for every new instance of the root aggregate whenever a root aggregate was fetched from the repository.
Wouldn't that be a bit of a undesirable trait to have to resubscribe for every instance? Would the application have to unsubscribe too?
Unless the events were declared as static, but I have heard bad things about static events and memory leaks. Would this be a concern?
If C# events were used, would they belong in the root aggregate or would they belong in the repository?
If the events were declared in the repository (which could be a Entity Framework Core DbContext) then when registered with the ASP.NET Core dependency handler using the .AddDbContext method it would be registered with the "Scoped" lifetime (once per client request), so unless the events were to be declared as static then the application would have to resubscribe on every new instance of the repository which would occur at every new incoming HTTP request.
Is using C# events for domain events in a application employing domain-driven design feasible or is it just an non-viable ill-fated idea?
Without distinguishing between C# Events and Domain Events it’s difficult to follow your narrative. However, if I understand your proposal correctly, you’re envisioning a C# component that listens to the Entity Event stream, then publishes those incoming domain events via C# events to listeners in the app. If that’s what you’re proposing then you would have to work hard to make it work, and it wouldn’t work well.
If we look at Mediatr, it subscribes to an event source and creates new command processors to process incoming domain events. The key is that it creates new command processors so it is able to call a method on them. Also, there is a one-to-one correspondence between a domain event and a command processor, and nothing is required at system startup other than Mediatr itself.
With C# Events the command processor is created by something, then registers itself to receive C# events of a particular type. The command processor initiates the link, not the event source subscriber. In order to process all kinds of events, at startup you would have to create at least one of each type of command processor and let it register itself as the receiver of the C# messages which carries the Domain Event as a payload.
Then what happens when you start to scale? Mediatr scales well because it creates a command processor for each Domain Event. Your proposal would not scale because to process 2 of the same event type you would need to manually create 2 command processors, and each of those command processors would receive BOTH of the incoming Domain Events because they are both subscribed to the same C# Event.
It is possible to code around all this mess, but that’s what Jimmy Bogard has already done. Instead of rewriting all that just fire up NuGet, pull down Mediatr, and then go play with your kids with all the time you saved.
It depends on the type of application.
If the application is a web application then it have a DbContext scoped to the life time of the HTTP request, and all the aggregates have a short life time too that lasts for the duration of the HTTP request. Hence registering the C# event handlers is cumbersome, also since you would have to do it after you fetch get the DbContext or the aggregate it would have to be inside the controller, repeatedly, everywhere. So for web applications using C# for events is a poor choice, and it a much better idea to delegate it to a singleton class as is done with MediatR.
If the application maintains a persistent DbContext that survives for the lifetime of the application and a root aggregate that survives for the lifetime of the application then you can could use C# events and just register the event handlers once. Such an application could be a command-line application, a background service, or a desktop application with a UI.

Avoiding captive dependencies when using delegates and events with an IOC Container

Say I have a console application or Windows service, and am using dependency injection with an IOC container (in my specific case, I'm using Autofac).
One of the classes that my IOC container resolves is a WorkDoer class, which has a long running DoWork(Args args) method. When DoWork(Args args) completes, a custom event is raised (WorkDone). In my case, DoWork is triggered as messages with parameters are taken off of a message queue.
I also have a Notifier class that I'd like to have subscribe to my WorkDone event.
Concretely
public class Notifier
{
public void Subscribe(WorkDoer w)
{
w.WorkDone += new WorkDoer.WorkDoneHandler(Notify);
}
private void Notify(WorkDoer w, EventArgs e)
{
//do some kind of notification decoupled from my WorkDoer
//concretely I'd like to push a SignalR message or something.
}
}
So now I have my WorkDoer which is responsible for running some long running business logic and raises an event. Then I in theory have my Notifier that can listen for that event and run some logic decoupled from my business logic, such as pushing a notification to an MVC page in that solution, or maybe publishes another message queue message, or something like that.
The projects in my solution are
App.WorkerService -- this contains my WorkDoer console app and my DependencyConfig
App.BusinessLogic -- this is a library that contains all of the business logic that WorkDoer uses
App.Notification -- this is where I'd like my Notifier(s) to live
So here's my problem:
In my WorkerService Program.cs, I have my WorkDoer registered with Autofac's Single Instance Scope. This means that it's a transient instance and can disappear. As such, I'm not sure how I can subscribe to it's WorkDone event effectively in my Program.cs's Main method, since it will eventually get disposed of. I could make it use a singleton scope to avoid this, but then I've captured all of WorkDoer's dependencies within that long running scope, which I don't want to do.
I have my Notifier in a singleton scope so that I don't lose existing subscriptions -- I'm not sure if that's bad practice or not, and I'm happy to change it.
Basically, the big picture is that I want to have my business logic in a separate project than my notification logic to avoid leaking notification code into my business logic. I'd also like to have the ability to easily add/remove/change notifier types (SignalR, log file, MQ, etc.). I'd like to use the C# event and delegate system for this (seems reasonably relevant here), but I'm not sure how to manage my dependency scopes.
I did see this question but I'd like to avoid the suggestions of OnActivated or the delegate registration because of the aforementioned captured dependency concerns.
Currently, you are using an observer design pattern for your notifications. You register the event handlers directly. That results in a tight coupling of the components.
For your requirements above, the publish/subscribe design pattern, using an event aggregator, would be better. The publisher and subscriber are only loosely coupled. Both know only the event aggregator. The event aggregator is injected into both and works as a mediator/facade/adapter.
There are many possible implementations. See:
https://www.codeproject.com/Articles/812461/Event-Aggregator-Pattern
https://www.martinfowler.com/eaaDev/EventAggregator.html
https://www.c-sharpcorner.com/UploadFile/pranayamr/publisher-or-subscriber-pattern-with-event-or-delegate-and-e/

Capturing Async events

Im struggling with a problem and need some options for possible solutions.
I have three layers - ClientApp, ServiceLayer and Domain Layer
The service layer and the domain layer implements a Publisher and Subscriber events pattern so that different areas of the domain can be notified when things happen.
The clientApp calls the domian to create a new order. On creation of the order the publisher raises an event to notify another are of the domain to do something. I am hooking into this event in the Service layer via a subscriber and the correct event is recieved.
I want the event to be bubbled up to the clientApp, but am struggling to get this to work. I think its because the events is trigger Asynchronously and are therefore not in the same thread. I have implemented a publish and subscriber between the clientApp and service layer, but again this failed.
ClientApp(create a new order)>ServiceLayer(recieves)>Domain(created order raises event)
ServiceLayer(recieves event)> ?????
Any help or guidance appreciated.

Force a service to close on Windows closing - Prism

I'm using a Prism and the MVVM pattern
I've got a service running in a repository that is registered in my container like this:
_container.RegisterType<ITheService, TheService>();
_container.RegisterType<IRepository<Order>, Repository>(new ContainerControlledLifetimeManager());
The constructor of the repository will subscribe to the service, that will then received new element (like 5 to 10 every second).
The problem is that because of this subscription, when i close the window of my GUI, the module holding the service is not closed, and the service keeps on running, instead of being shut down by the dispose.
If i wasn't in MVVM i would just unsubsribe the service when i close the the window, but the shell window can't do that.
I see 2 solutions
* have an eventaggregator that will let my repository know when the shell close, and then unsubscribe the service (not sure it would work though)
* resolve the repository from the shell (as it's registered as a singleton), and unsubscribe when the service, but that would be very ugly....
So i tried my first idea, which was using an EventAggregator.
The shell publish an event in the EventAggregator when the Closed event is fired.
The repository holding the service has subscribed to that event, and will get notified when the shell close. So i just need to close the service when i get the notification...

How to include Listener type class in the WPF/MVVM pattern?

Imagine you have Listener class that will connect on app start to some server with Connect method, then it starts to listen to messages and on every received message it raises event OnRecievedMessage. Based on these messages you need to update viewmodels which in turn update views. What's more you have to run Listen() method on new thread in order to don't block UI, so event OnRecievedMessage will also run on this new thread.
How would you incorporate such class in structure of WPF/MVVM application and how to connect it with viewmodel?
In this scenario I would not use an event - I would expose IObservable<T>
Because the IObservable will be an object and can be easily passed and returned to/from a function you gain:
easily inject this into your Viewmodel
filter/map and dispatch to the UI-Thread
unhook the handlers easier (Dispose vs. "-=")
So don't pass your "Listener" class around - pass the IObservable you implement/expose there around!
Make sure to have a look at the Rx-Framework

Categories