-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How can I use an INotificationHandler as singleton instance? #519
Comments
If I recall correctly that is all up to how you do register your handlers. Just pointing that out in order to give you the pointers to where you should look. It's not the MediatR by itself, but rather the registering part on your application startup |
If you are using the MediatR.Extensions.Microsoft.DependencyInjection library then it this library that is taking care of the registration for you. Depending on your use case I would suspect that you may not actually need the INotificationHandler to be the singleton, but a singleton dependency into that handler in order to accomplish your goal. |
Let me show my case , it‘s’ a console app and registered some BackgroundService like this:
And the TestService is like this:
In thie case, everytime other service publish the TestNotification, the TestService's constructor is called, This significantly increases object allocation and GC pressure for heavy workloads, but TestService has been registered as singleton service by .Net Core DI container. |
Thank you for your reply and this is my case: |
None of what you have shown particularly describes your use case, just the way you have currently set up your classes. I don't see any reason for your notification handler and background service to be the same class. If they need to share functionality or communicate they should have some sort of way to communicate through dependencies IMO. |
^^ your background service should NOT be a notification handler. Build the types to do something else, keeping in mind a background service is registered as a singleton. |
I build a new NotificationHandler to handle notification now 。Is there any way I can control the life of NotificationHandler?I find INotificationHandler<> is registered as Transient in the source code. |
You can change this in the companion MediatR.Extensions.Microsoft.DependencyInjection library - but be VERY careful in doing so. You really should not need to change the lifecycle of handlers - instead you control the lifecycle of dependencies injected into the handlers. Handlers should not have state - and therefore should be transient. |
Just to contribute to this thread, I wanted to show how I achieved having a Singleton handler: services.AddSingleton<
IRequestHandler<BrokerPaymentRequestCommand, Result<List<BrokerPaymentResponse>>>,
BrokerPaymentHandler
>();
services.AddMediatR(c => {
c.RegisterServicesFromAssemblyContaining(typeof(BrokerPaymentRequestCommand));
c.Lifetime = ServiceLifetime.Singleton;
}); Just by registering the handler manually before calling AddMediatR, he stays singleton. I also want to talk about our approach to creating applications with all services singleton (except the controllers): I know there are some concerns, for example, with the database connection scope. In our case, we're using Dapper in a aspnet.core application and created a Database Session class to manage the connection using AsyncLocal. It helps to make the connection to be acquired as late as possible, and to be returned to the pool as soon as possible, letting the connection be associated only with the current Task flow, ie, exclusively with the current request, making the scope of the services irrelevant, at least for that aspect. I know in .net we tend to use Request Scope or Transient injection to deal with request isolation, but using only singletons brings some good benefits:
The use of AsyncLocal doesn't come without cost, though. It also has some overhead and I don't know when it starts to become greater than DI instantiation overhead. I mean I don't know any performance comparison between the number of instantiating classes vs the number of AsyncLocal uses. But at least for our scenarios, it made the application simpler to maintain and to keep performant. |
by default, MediatR will create an INotificationHandler instance when Publish method is called.
What I want is that MediatR call the INotificationHandler singleton instance once .
Anyone can show me the usage??
Thanks!!
The text was updated successfully, but these errors were encountered: