I have a slightly modified version of Mediatr handing command processing in my application. I have implemented a MediatorPipeline that allows me to have pre and post processors.
public class AsyncMediatorPipeline<TRequest, TResponse>
: IAsyncRequestHandler<TRequest, TResponse>
where TRequest : IAsyncRequest<TResponse>
{
private readonly IAsyncRequestHandler<TRequest, TResponse> inner;
private readonly IAsyncPreRequestHandler<TRequest>[] preRequestHandlers;
private readonly IAsyncPostRequestHandler<TRequest,TResponse>[] postRequestHandlers;
public AsyncMediatorPipeline(IAsyncRequestHandler<TRequest, TResponse> inner,
IAsyncPreRequestHandler<TRequest>[] preRequestHandlers,
IAsyncPostRequestHandler<TRequest, TResponse>[] postRequestHandlers)
{
this.inner = inner;
this.preRequestHandlers = preRequestHandlers;
this.postRequestHandlers = postRequestHandlers;
}
public async Task<TResponse> Handle(TRequest message)
{
foreach (var preRequestHandler in preRequestHandlers)
{
await preRequestHandler.Handle(message);
}
var result = await inner.Handle(message);
foreach (var postRequestHandler in postRequestHandlers)
{
await postRequestHandler.Handle(message, result);
}
return result;
}
}
I am registering my pre-processors with autofac like so:
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.As(type => type.GetInterfaces()
.Where(type => type.IsClosedTypeOf(typeof(IAsyncPreRequestHandler<>))))
.InstancePerLifetimeScope();
At runtime I am getting duplicate preprcessors. I have to filter the set removing duplicates. I am not sure why this is happening. If i comment out the registration, I do not get any preprocessors, which indicates that I am not duplicating the registration somewhere else.
Update: Here are some more details on the type that appears to be getting registered twice. The various class definitions:
The concrete handler
public class ClientEditorFormIdentifierValidationHandler
: IAsyncPreRequestHandler<AddOrEditClientCommand>{}
The command class
public class AddOrEditClientCommand
: IAsyncRequest<ICommandResult>{}
The command interface
public interface IAsyncRequest<out TResponse> { }
After extensive troubleshooting, I discovered that I was in fact registering my handlers twice. I like to use Autofac Modules to breakup the configuration of my container into manageable chunks.
In my MVC5 Startup class I register my modules like so:
builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
Buried deep within an "InfrastructureModule" class was the line:
builder.RegisterModule<MediatorModule>();
Which was of course reregistering my mediator handlers... DUH..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With