我们有许多通用命令处理程序,它们是由Autofac以开放式通用方式注册的。我们有装饰所有手柄的几个装饰器。现在我只需要为一个命令处理程序注册一个装饰器,而不会影响所有其他命令处理程序。这是我的尝试,但我似乎没有获得注册权。只为一个通用命令处理程序注册Autofac装饰器
下面是简单的测试代码是类似于我们的代码:
我们有数百个这样工作的命令:
class NormalCommand : ICommand { }
// This command handler should not be decorated
class NormalCommandHandler : ICommandHandler<NormalCommand>
{
public void Handle(NormalCommand command) { }
}
而且我想在装饰ONLY TestCommandHandler
包裹TestCommandHandlerDecorator
class TestCommand : ICommand { }
// And I would like to put decorator around this handler
class TestCommandHandler : ICommandHandler<TestCommand>
{
public void Handle(TestCommand command) { }
}
// This decorator should be wrapped only around TestCommandHandler
class TestCommandHandlerDecorator : ICommandHandler<TestCommand>
{
private readonly ICommandHandler<TestCommand> decorated;
public TestCommandHandlerDecorator(ICommandHandler<TestCommand> decorated)
{
this.decorated = decorated;
}
public void Handle(TestCommand command)
{
// do something
decorated.Handle(command);
// do something again
}
}
这就是我如何注册我的组件:
static class AutofacRegistration
{
public static IContainer RegisterHandlers()
{
var builder = new ContainerBuilder();
//Register All Command Handlers but not decorators
builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(AutofacRegistration)))
.Where(t => !t.Name.EndsWith("Decorator"))
.AsClosedTypesOf(typeof(ICommandHandler<>))
.InstancePerLifetimeScope();
// and here is the battle!
builder.RegisterType<TestCommandHandler>()
.Named<ICommandHandler<TestCommand>>("TestHandler")
.InstancePerLifetimeScope();
// this does not seem to wrap the decorator
builder.RegisterDecorator<ICommandHandler<TestCommand>>(
(c, inner) => new TestCommandHandlerDecorator(inner),
fromKey: "TestHandler")
.Named<ICommandHandler<TestCommand>>("TestHandler1")
.InstancePerLifetimeScope();
return builder.Build();
}
}
这就是我如何努力,以确认我得到命令处理程序/装饰的正确实例:
class AutofacRegistrationTests
{
[Test]
public void ResolveNormalCommand()
{
var container = AutofacRegistration.RegisterHandlers();
var result = container.Resolve<ICommandHandler<NormalCommand>>();
// this resolves correctly
Assert.IsInstanceOf<NormalCommandHandler>(result); // pass
}
[Test]
public void TestCommand_Resolves_AsDecorated()
{
var container = AutofacRegistration.RegisterHandlers();
var result = container.Resolve<ICommandHandler<TestCommand>>();
// and this resolves to TestCommandHandler, not decorated!
Assert.IsInstanceOf<TestCommandHandlerDecorator>(result); // FAILS!
}
}
正如评论说,是没有得到应用的装饰,装饰注册将被忽略。
任何ides如何注册这个装饰器?我究竟做错了什么?
我可以提供使用其他的DI容器的解决方案,还是你迷上了Autofac? – Steven
我刚刚迷上了Autofac,但如果您可以在Structure Map或Windsor中举例,我也会对此感兴趣。为了教育目的。 – trailmax