のために私たちは、オープン一般的な方法でAutofacによって登録されている一般的なコマンドハンドラがたくさんあります。すべてのハンドルを飾るカップルデコレータがあります。今では、1つのコマンドハンドラだけにデコレータを登録し、他のすべてのコマンドハンドラには影響を与えません。ここで私の試みですが、私は登録権を得ていないようです。ここで登録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!
}
}
コメントが言うように、デコレータはデコレータ登録が無視され、適用される取得されていません。
このデコレータを登録する方法を任意のIDE ??私は間違って何をしていますか?
私は別のDIコンテナを使用してソリューションを提供することができます、またはあなたはオートファックに夢中になっていますか? – Steven
私は今Autofacに夢中になっていますが、Structure MapやWindsorで例を挙げることができれば、私もそれを調べることに興味があります。教育目的のため。 – trailmax