Autofac:实现未注入非泛型接口的泛型类

本文关键字:泛型接口 泛型类 注入 实现 Autofac | 更新日期: 2023-09-27 18:30:47

假设我有以下(简化的)对象模型:

public abstract class Message
{
}
public class SimpleMessage:Message
{
}
public class ComplexMessage:Message
{
}
public interface IMessageHandler{
    void Handle(Message message);
}
public class NonGenericMessageHandler1: IMessageHandler{
    void Handle(Message message){      
      Console.WriteLine("hi dad!")
    }
}   
public class NonGenericMessageHandler2: IMessageHandler{
    void Handle(Message message){        
      Console.WriteLine("hi mom!")
    }
}
public class GenericMessageHandler<T> :IMessageHandler where T: Message>{ 
    void Handle(Message message){
        //do something cool with the generic
    }
}   
 public class MessageHandlerFactory: IMessageHandlerFactory{
    public MessageHandlerFactory(IEnumerable<IMessageHandler> handlers){
    }
    public IMessageHandler Create(Message message){
         //return the right handler
    }   
 }

问题来了。 autofac 注入到 MessageHandlerFactory 中的IEnumerable<IMessageHandler>仅包含 IMessageHandler .
的非泛型实现如果我想要通用版本,我必须手动声明各种封闭版本,如下所示:

 public MessageHandlerFactory(IEnumerable<IMessageHandler> handlers, MessageHandler<SimpleMessage> handler1, MessageHandler<ComplexMessage> handler2){
 }

以下是我连接Autofac的方式:

  builder.RegisterAssemblyTypes(typeof (IMessageHandlerFactory).Assembly)
                 .AsImplementedInterfaces()
                 .AsSelf()
                 .SingleInstance();
          builder.RegisterGeneric(typeof (MessageHandler<>)).AsSelf().SingleInstance();

如何让 Autofac 传入所有IMessageHandler实现器(包括任何泛型变体)的统一集合?

Autofac:实现未注入非泛型接口的泛型类

所以我想我想通了。 它归结为鸡或蛋的情况。 当您通过 RegisterGeneric 方法注册泛型类时,Autofac 不会自动注册封闭的类型,除非它在对象图中的某个位置将它们检测为依赖项。

Ctor 1 不会触发要注册的已关闭泛型:

   public MessageHandlerFactory(IEnumerable<IMessageHandler> handlers){
   }

Ctor 2 确实会触发要注册的封闭泛型:

   public MessageHandlerFactory(IEnumerable<IMessageHandler> handlers,
                                MessageHandler<ComplexMessage> complexHandler,
                                MessageHandler<SimpleMessage> simpleHandler
){}

一旦我使用以下代码手动注册了封闭的泛型,Autofac 就开始将它们作为 Ctor 1 上看到的IEnumerable<IMessageHandler>依赖项的一部分注入

builder.RegisterType(typeof(MessageHandler<ComplexMessage>)).AsImplementedInterfaces();
builder.RegisterType(typeof(MessageHandler<SimpleMessage>)).AsImplementedInterfaces();