我有两个不同的服务(实体框架上下文),我在我的应用程序中注入并注册如下:
builder.Register<WriteContext>().Named("Write");
builder.Register<ReadContext>().Named("Read");
现在,我有两个不同的命令处理程序(我有两个以上),每个都注入一个DbContext
如下:
public class CommandAHandler : ICommandHandler {
private readonly DbContext context;
// this handler should get "Write" context
public CommandAHandler(DbContext context) {
this.context = context;
}
}
public class CommandBHandler : ICommandHandler {
private readonly DbContext context;
// this handler should get "Read" context
public CommandBHandler(DbContext context) {
this.context = context;
}
}
如何指定CommandAHandler来获取类型&#34的实例;写&#34;和CommandBHandler获取类型&#34的实例;阅读&#34;?当然,使用Autofac注册
答案 0 :(得分:2)
您违反了此处的Liskov Substitution Principle(因此也违反了SOLID原则)。你有一个'抽象'(即DbContext
),但是如果你将只读版本注入一个期望可写的消费者,应用程序就会中断。这强烈表明您违反了LSP。
LSP规定每个案例都有不同的抽象。这基本上意味着你应该直接注入ReadContext和WriteContext。这将立即解决您的注册问题,因为您可以将处理程序定义为:
public CommandAHandler(WriteContext context)
public CommandBHandler(ReadContext context)
这使您可以将注册简化为以下内容:
builder.Register<WriteContext>();
builder.Register<ReadContext>();
答案 1 :(得分:1)
您可以使用lambda表达式将处理程序注册到Ioc中。例如:
authentication entry point
答案 2 :(得分:0)
假设WriteContext
和ReadContext
注册为DbContext
:
builder
.RegisterType<CommandAHandler>()
.WithParameters(
new[] {
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(DbContext),
(pi, ctx) => ctx.ResolveNamed<DbContext>("Write")
)
});
builder
.RegisterType<CommandBHandler>()
.WithParameters(
new[] {
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(DbContext),
(pi, ctx) => ctx.ResolveNamed<DbContext>("Read")
)
});