我們有許多通用命令處理程序,它們是由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