【发布时间】:2012-12-20 18:29:46
【问题描述】:
我有两个装饰器:
class DbCommandWithTransactionHandlerDecorator<TCommand>
: IDbCommandHandler<TCommand> { ... }
class DbOptimisticConcurrencyRetryDecorator<TCommand>
: IDbCommandHandler<TCommand> { ... }
这些装饰器将事务管理和乐观并发重试功能添加到数据库命令中。
我使用 Autofac 作为我的 IoC 容器。我想设置 Autofac 以便它自动连接在程序集中找到的所有 IDbCommandHandler<>,这样当我请求说 IDbCommandHandler<CreateNewNotificationCommand> 时,它会首先用 DbCommandWithTransactionHandlerDecorator 自动装饰它,然后是 @987654325 @。
我一直在尝试使用 Autofac 的 builder.RegisterGenericDecorator() 来解决这个问题,但还没有成功。主要问题是装饰器需要一个“命名”参数才能工作。下面是最“接近”我想要实现的示例代码 - 但是主要缺陷是我仍然必须手动注册类型。
var builder = new ContainerBuilder();
var a = Assembly.GetExecutingAssembly();
// I need to find a way how these can be 'auto-wired',
// rather than having to manually wire each command.
builder.RegisterType<CreateNewNotificationCommandHandler>()
.Named<IDbCommandHandler<CreateNewNotificationCommand>>("command");
builder.RegisterType<CreateNewNotificationCommandHandler_2>()
.Named<IDbCommandHandler<CreateNewNotificationCommand_2>>("command");
builder.RegisterGenericDecorator(
typeof(DbCommandWithTransactionHandlerDecorator<>),
typeof(IDbCommandHandler<>),
fromKey: "command");
var container = builder.Build();
var handler1 =
container.Resolve<IDbCommandHandler<CreateNewNotificationCommand>>();
var handler2 =
container.Resolve<IDbCommandHandler<CreateNewNotificationCommand_2>>();
handler1.Handle(null); //these are correctly decorated
handler2.Handle(null); //these are correctly decorated
【问题讨论】:
-
@Steven 我确实设法找到了 Autofac 的解决方法,其中涉及对类型进行手动反射搜索并映射它们。然而,今天早些时候我尝试了 Simple Injector,正如我在您昨天发布的文章中看到的那样 - 我只能说它非常出色且非常易于使用 - 对此表示敬意:)
标签: c# dependency-injection inversion-of-control autofac