I'm using MediatR 9.0.0 (with MediatR.Extensions.Microsoft.DependencyInjection 9.0.0). I have event notification handler like that:
public class StatusChangedEventHandler : INotificationHandler<StatusChangedEvent>
{
public StatusChangedEventHandler ()
{
}
public async Task Handle(StatusChangedEvent evnt, CancellationToken cancellationToken)
{
//some code
}
}
The event is being published from another command handler:
public class ChangeStatusCommandHandler : IRequestHandler<ChangeStatusCommand, bool>
{
...
private readonly IMediator _mediator;
public ChangeStatusCommandHandler(...,IMediator mediator)
{
...
_mediator = mediator;
}
public async Task<bool> Handle(ChangeStatusCommand command, CancellationToken cancellationToken)
{
...
await _mediator.Publish(new StatusChangedEvent(int id, string message));
...
}
}
The problem is StatusChangedEventHandler.Handle method is being called multiple times - I noticed it seems to be relative to number of command handlers registered in Startup.cs, e.g.
services.AddMediatR(typeof(CommandA));
=> the handler would be called once
services.AddMediatR(typeof(CommandA));
services.AddMediatR(typeof(CommandB));
=> the handler would be called twice
services.AddMediatR(typeof(CommandA));
services.AddMediatR(typeof(CommandB));
services.AddMediatR(typeof(CommandC));
=> the handler would be called 3 time etc.
How to fix that to make handler being called just once?
A call to services.AddMediatR(typeof(CommandA))
doesn't only register that single command handler CommandA
, it registers all command handlers that are present in the assembly containing CommandA
; the full assembly is being scanned for its handlers.
From the documentation
Scans assemblies and adds handlers, preprocessors, and postprocessors implementations to the container. To use, with an IServiceCollection instance:
You must not explicitly call AdMediatR
upon the other command handlers;
remove the ones below.
services.AddMediatR(typeof(CommandB));
services.AddMediatR(typeof(CommandC));