Mamy wiele ogólnych procedur obsługi komend, które są rejestrowane przez Autofac w sposób otwarty generyczny. Mamy kilka dekoratorów, które zdobią wszystkie uchwyty. Teraz muszę zarejestrować dekorator tylko dla jednej procedury obsługi i nie wpływać na wszystkie inne procedury obsługi komend. Oto moja próba, ale wydaje mi się, że nie mam prawa do rejestracji.Zarejestruj dekorator Autofac tylko dla jednej ogólnej obsługi komend
Oto prosty kod test, który jest podobny do naszego kodu:
mamy setki poleceń roboczych tak:
class NormalCommand : ICommand { }
// This command handler should not be decorated
class NormalCommandHandler : ICommandHandler<NormalCommand>
{
public void Handle(NormalCommand command) { }
}
i chciałbym zawinąć TYLKO TestCommandHandler
w dekoratora 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
}
}
W ten sposób rejestruję swoje komponenty:
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();
}
}
I tak staram się potwierdzić, że mam odpowiednie instancje wozy dowodzenia/dekoratorów:
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!
}
}
Jako komentarz mówi dekorator nie jest stosowana coraz rejestracja dekorator jest ignorowany.
Jakieś sposoby rejestracji tego dekoratora? Co ja robię źle?
Mogę zapewnić rozwiązanie przy użyciu innego kontenera DI czy jesteś uzależniony od Autofac? – Steven
Jestem teraz uzależniony od Autofac, ale jeśli możesz podać przykłady w Mapie Struktury lub Windsor, również będę zainteresowany. Do celów edukacyjnych. – trailmax