Autofac: ocultando várias implementações contravariantes atrás de um composto

Foi acionado poresta questão SOobre o suporte a covariância e contravariância do (.NET 4.0) para Autofac, e agora estou tentando obter algo semelhante, mas sem sort

O que estou tentando alcançar é configurar o Autofac de tal maneira que, quando resolvo um únicoIEventHandler<TEvent> (para fins de demonstração usandocontainer.Resolve, mas normalmente, é claro, usando injeção de construtor), o Autofac retornará umMultipleDispatchEventHandler<TEvent> que agrupa todos os manipuladores de eventos registrados atribuíveis a partir do manipulador solicitad

Em outras palavras, quando escrevo isto:

var handler = container
    .GetInstance<IEventHandler<CustomerMovedEvent>>();

handler.Handle(new CustomerMovedEvent());

Com relação ao design do aplicativo (fornecido abaixo), eu esperaria umMultipleDispatchEventHandler<CustomerMovedEvent> a ser retornado que envolve umCustomerMovedEventHandler eNotifyStaffWhenCustomerMovedEventHandler.

qui está o design do aplicativo:

// Events:
public class CustomerMovedEvent { }

public class CustomerMovedAbroadEvent : CustomerMovedEvent { }

public class SpecialCustomerMovedEvent : CustomerMovedEvent { }


// Event handler definition (note the 'in' keyword):
public interface IEventHandler<in TEvent> 
{
    void Handle(TEvent e);
}

// Event handler implementations:
public class CustomerMovedEventHandler
    : IEventHandler<CustomerMovedEvent>
{
    public void Handle(CustomerMovedEvent e) { ... }
}

public class NotifyStaffWhenCustomerMovedEventHandler
    : IEventHandler<CustomerMovedEvent>
{
    public void Handle(CustomerMovedEvent e) { ... }
}

public class CustomerMovedAbroadEventHandler
    : IEventHandler<CustomerMovedAbroadEvent>
{
    public void Handle(CustomerMovedAbroadEvent e) { ... }
}

Esta é a definição deMultipleDispatchEventHandler<TEvent>, definido na Raiz da composição:

// A composite wrapping possibly multiple handlers.
public class MultipleDispatchEventHandler<TEvent>
    : IEventHandler<TEvent>
{
    private IEnumerable<IEventHandler<TEvent>> handlers;

    public MultipleDispatchEventHandler(
        IEnumerable<IEventHandler<TEvent>> handlers)
    {
        this.handlers = handlers;
    }

    public void Handle(TEvent e)
    {
        this.handlers.ToList().ForEach(h => h.Handle(e));
    }
}

Esta é minha configuração atual:

var builder = new ContainerBuilder();

// Note the use of the ContravariantRegistrationSource (which is 
// available in the latest release of Autofac).
builder.RegisterSource(new ContravariantRegistrationSource());

builder.RegisterAssemblyTypes(typeof(IEventHandler<>).Assembly) 
    .AsClosedTypesOf(typeof(IEventHandler<>));

// UPDATE: I'm registering this last as Kramer suggests.
builder.RegisterGeneric(typeof(MultipleDispatchEventHandler<>))
    .As(typeof(IEventHandler<>)).SingleInstance();

var container = builder.Build();

Com a configuração atual, o aplicativo falha durante a chamada paraResolve, com a seguinte exceção:

Autofac.Core.DependencyResolutionException: Dependência de componente circular detectada: MultipleDispatchEventHandler'1 [[SpecialCustomerMovedEvent]] -> IEventHandler'1 [[SpecialCustomerMovedEvent]] [] -> MultipleDispatchEventHandler'1 [[SpecialCustomerMovedEvent

gora, a questão é clara: como posso corrigir a configuração (ou o design) para suportar iss

questionAnswers(2)

yourAnswerToTheQuestion