【发布时间】:2017-11-13 21:32:19
【问题描述】:
我有一个应用程序,其中我的DbContext 实现有多个连接字符串。为了在消费类中支持这一点,我创建了一个带有Get 方法的IDbContextProvider 接口,它可以为我提供我需要的DbContext 实例。
我也有一个ICommandHandler 的东西,我正在尝试创建一个装饰器,它将在命令执行成功时调用DbContext.SaveChangesAsync()。我正在像这样注册我的装饰器:
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(SaveChangesCommandHandlerDecorator<>));
现在,因为我不想为DbContext 实现添加类型参数,而且我知道从DbContext 派生的所有类都有SaveChangesAsync() 方法,所以我想我可以使用协方差。所以我的界面是这样的:
public public interface IDbContextProvider<out TDbContext> where TDbContext : DbContext
{
TDbContext Get(DbPrivileges privileges);
}
以及我的装饰器的相关部分:
public class SaveChangesCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand>
where TCommand : ICommand
{
private readonly ICommandHandler<TCommand> _handler;
private readonly IDbContextProvider<DbContext> _dbContextProvider;
public SaveChangesCommandHandlerDecorator(
ICommandHandler<TCommand> handler, IDbContextProvider<DbContext> dbContextProvider)
{
_handler = handler;
_dbContextProvider = dbContextProvider;
}
...
但是,当我在容器上调用 Verify() 时,它抱怨 IDbContextProvider 无效,因为它正在寻找“基础”IDbContextProvider<DbContext> 而不是在我的应用中注册的其中之一。
SaveChangesCommandHandlerDecorator
类型的构造函数包含名称为“dbContextProvider”且类型为 IDbContextProvider 的未注册参数。请确保 IDbContextProvider 已注册,或更改 SaveChangesCommandHandlerDecorator 的构造函数。请注意,存在不同类型 (Redacted).IDbContextProvider 的注册,而请求的类型是 (Redacted).IDbContextProvider 。
这实际上是有道理的,因为 Simple Injector 无法知道将什么具体类型注入到 dbContextProvider 参数中。
是否有任何方法可以自定义我的装饰器的创建方式,以便它可以查看底层 ICommandHandler 实现的依赖项的依赖项,并在创建时从那里选择 IDbContextProvider 签名?所以如果我的命令处理程序有一个IDbContextProvider<AwesomeDbContext>,我希望我的装饰器也能解决这个问题。
【问题讨论】:
标签: c# dependency-injection ioc-container simple-injector