Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofac resolves multiple instances of the same type

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> { }
like image 229
NotMyself Avatar asked Mar 09 '15 21:03

NotMyself


1 Answers

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..

like image 125
NotMyself Avatar answered Nov 07 '22 05:11

NotMyself