Mediatr handlers are they singletons?

Viewed 4776

I am using the Mediatr in my .Net Core project and I was wondering if the handler's in the Mediatr are singleton's or are the new instances for every Send request; I know the Mediatr is a Singleton' but for the handlers it uses for a command or query, I am not very sure.

I tend to think they would also be singletons; but just wanted to double confirm.

3 Answers

For the handlers, after following the source code, it looks like they are all added as Transient.

https://github.com/jbogard/MediatR.Extensions.Microsoft.DependencyInjection/blob/1519a1048afa585f5c6aef6dbdad7e9459d5a7aa/src/MediatR.Extensions.Microsoft.DependencyInjection/Registration/ServiceRegistrar.cs#L57

services.AddTransient(@interface, type);

For the IMediator itself, it looks like it is lifetime by default :

https://github.com/jbogard/MediatR.Extensions.Microsoft.DependencyInjection/blob/1519a1048afa585f5c6aef6dbdad7e9459d5a7aa/src/MediatR.Extensions.Microsoft.DependencyInjection/Registration/ServiceRegistrar.cs#L223

services.Add(new ServiceDescriptor(typeof(IMediator), serviceConfiguration.MediatorImplementationType, serviceConfiguration.Lifetime));

Note that the service configuration is a configuration object that unless somehow you change it along it's default path, will be set to transient too :

public MediatRServiceConfiguration()
{
    MediatorImplementationType = typeof(Mediator);
    Lifetime = ServiceLifetime.Transient;
}

Using core you can manually register your handlers and use whatever scope you want. So for example:

services.AddScoped<IPipelineBehavior<MyCommand>, MyHandler>();

We actually wrap Mediatr so we can add various bits and bobs so it ends up being a registration extension like this (CommandContect/QueryContext holds various stuff we use all the time and ExecutionResponse is a standard response so we can have standard post handlers that know what they are getting):

public static IServiceCollection AddCommandHandler<THandler, TCommand>(this IServiceCollection services)
            where THandler : class, IPipelineBehavior<CommandContext<TCommand>, ExecutionResponse>
            where TCommand : ICommand
        {
            services.AddScoped<IPipelineBehavior<CommandContext<TCommand>, ExecutionResponse>, THandler>();
            return services;
        }

Which is used like this:

services.AddCommandHandler<MyHandler, MyCommand>();

We have similar for queries (AddQueryHandler<.....)

Hope that helps

Related