具有同一接口的多种实现的Autofac [英] Autofac with multiple implementations of the same interface
问题描述
我正在使用Autofac,并且希望有一个接口的多个实现.如何配置Autofac,以便根据当前类型解析依赖关系?
I'm using Autofac and would like to have multiple implementations of an interface. How can I configure Autofac so to resolve dependencies based on the current type?
更具体地说,我有一个接口和应该链接在一起的多个实现.
More specifically, I have one interface and multiple implementations that should be chained together.
让我解释一下(虚拟课):
Let me explain (fictitious classes):
public interface IMessageHandler
{
void Handle(Message message);
}
public class LoggingMessageHandler : IMessageHandler
{
private IMessageHandler _messageHandler;
public LoggingMessageHandler(IMessageHandler messageHandler)
{
_messageHandler = messageHandler;
}
public void Handle(Message message)
{
// log something
_messageHandler.Handle(message);
}
}
public class DoSomethingMessageHandler : IMessageHandler
{
private IMessageHandler _messageHandler;
public DoSomethingMessageHandler (IMessageHandler messageHandler)
{
_messageHandler = messageHandler;
}
public void Handle(Message message)
{
// do something
_messageHandler.Handle(message);
}
}
在链的底部可能是一个IMessageHandler
,它不会将消息传递给下一个消息.
At the bottom of the chain might be an IMessageHandler
that doesn't pass the message on to the next one.
如果我想要以下链:
TopLevelClass -> LoggingMessageHandler -> DoSomethingMessageHandler -> FinalHandler
如何告诉Autofac
How can I tell Autofac to
- 将
LoggingMessageHandler
传递给TopLevelClass
(以实现对IMessageHandler
的依赖) - 将
DoSomethingMessageHandler
传递给LoggingMessageHandler
(以实现对IMessageHandler
的依赖) - 将
LoggingMessageHandler
传递给FinalHandler
(以实现对IMessageHandler
的依赖)
- pass
LoggingMessageHandler
toTopLevelClass
(to fulfill its dependency onIMessageHandler
) - pass
DoSomethingMessageHandler
toLoggingMessageHandler
(to fulfill its dependency onIMessageHandler
) - pass
LoggingMessageHandler
toFinalHandler
(to fulfill its dependency onIMessageHandler
)
是否有可能(我已经阅读了对IEnumerable的隐式支持) ?还是我必须在两者之间使用额外的类(工厂之类的东西)?
Is it even possible (I have read about the implicit support for IEnumerable)? Or will I have to use an extra class in between (a factory or something)?
推荐答案
此处有4个选项: https://autofaccn.readthedocs.io/en/latest/faq/select-by-context.html
选项1:重新设计界面
ILoggingMessageHandler , IDoSomethingMessageHandler
选项2:更改注册
builder.Register(ctx => new FinalHandler(ctx.Resolve<LoggingMessageHandler >()));
or
builder.Register(ctx => new FinalHandler(ctx.Resolve<IDoSomethingMessageHandler >()));
选项3:使用键控服务
builder.RegisterType<FinalHandler>()
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(IMessageHandler),
(pi, ctx) => ctx.ResolveKeyed<ISender>("something")));
选项4:使用元数据
public class FinalHandler
{
public FinalHandler([WithMetadata("sendBy", "something")] IMessageHandler messageHandler) { ... }
}
这篇关于具有同一接口的多种实现的Autofac的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!