Chúng tôi có rất nhiều trình xử lý lệnh chung được đăng ký bởi Autofac theo kiểu mở chung. Chúng tôi có vài trang trí trang trí tất cả các tay cầm. Bây giờ tôi cần phải đăng ký một trang trí cho chỉ một trình xử lý lệnh và không ảnh hưởng đến tất cả các trình xử lý lệnh khác. Đây là nỗ lực của tôi về điều đó, nhưng tôi dường như không nhận được quyền đăng ký.Đăng ký bộ trang trí Autofac cho chỉ một bộ xử lý lệnh chung
Đây là mã kiểm tra đơn giản tương tự như mã của chúng tôi:
Chúng tôi có hàng trăm các lệnh làm việc như thế này:
class NormalCommand : ICommand { }
// This command handler should not be decorated
class NormalCommandHandler : ICommandHandler<NormalCommand>
{
public void Handle(NormalCommand command) { }
}
Và tôi muốn quấn CHỈ TestCommandHandler
trong trang trí 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
}
}
Đó là cách tôi đăng ký thành phần của mình:
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();
}
}
Và đây là cách tôi cố gắng xác nhận rằng tôi nhận được trường hợp đúng đắn về xử lý lệnh/trang trí:
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!
}
}
Khi bình luận nói, trang trí không nhận được áp dụng, đăng ký trang trí được bỏ qua.
Bất kỳ id nào cách đăng ký trang trí này ?? Tôi đang làm gì sai?
Tôi có thể cung cấp một giải pháp sử dụng một container DI , hoặc bạn đang nối với Autofac? – Steven
Tôi đang nối với Autofac ngay bây giờ, nhưng nếu bạn có thể đưa ra ví dụ trong Bản đồ Cấu trúc hoặc Windsor, tôi cũng sẽ quan tâm để xem xét điều đó. Vì mục đích giáo dục. – trailmax