假设我有以下(简化的)对象模型:
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
实现器(包括任何泛型变体)的统一集合?
所以我想我想通了。 它归结为鸡或蛋的情况。 当您通过 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();