使用RegisterAssemblyTypes时如何使用Autofac注册装饰器?
这是我的代码使用RegisterAssemblyTypes时如何使用Autofac注册装饰器?
public interface ICommandHandler<T>
{
void Handle(T command);
}
public class CreateUserCommandHandler : ICommandHandler<CreateUserCommand>
{
public void Handle(CreateUserCommand command)
{
// do something with the command
}
}
public class LoggingCommandDecorator<TCommand> : ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> _commandHandler;
public LoggingCommandDecorator(ICommandHandler<TCommand> commandHandler)
{
_commandHandler = commandHandler;
}
public void Handle(TCommand command)
{
Debug.WriteLine("Logging...");
_commandHandler.Handle(command);
}
}
这里是我的注册:
private void SetupAutofac()
{
var builder = new ContainerBuilder();
// Register your MVC controllers.
builder.RegisterControllers(typeof(WebApiApplication).Assembly);
// OPTIONAL: Register model binders that require DI.
builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
builder.RegisterModelBinderProvider();
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
builder.RegisterAssemblyTypes(assemblies)
.As(o => o.GetInterfaces()
.Where(i => i.IsClosedTypeOf(typeof(ICommandHandler<>)))
.Select(i => new KeyedService("Handler", i)));
builder.RegisterGenericDecorator(typeof(LoggingCommandDecorator<>),
typeof(ICommandHandler<>),
"Handler", "DecoratedHandler");
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
当我运行这段代码,我得到以下异常:
建设者没有发现 可以使用0123调用'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'类型 'AspectDemo.Controllers.HomeController'可用服务和参数:无法解析参数 'AspectDemo.Business.ICommandHandler
1[AspectDemo.Business.Users.CreateUserCommand] createUserHandler' of constructor 'Void .ctor(AspectDemo.Business.ICommandHandler
1 [AspectDemo.Business.Users.CreateUserCommand])'。
当我使用以下作为我的注册,我没有得到异常,但我也没有任何装饰。
builder.RegisterAssemblyTypes(assemblies)
.AsClosedTypesOf(typeof(ICommandHandler<>))
.AsImplementedInterfaces();
我该怎么做才能使用装饰器?
注:现在我只是使用一个装饰器,但最终我认为我有大约4-5个装饰器。
当您使用RegisterGenericDecorator
方法的toKey
参数,它导致了一个名为注册,所以你必须要解决的一个名为ICommandHandler
builder.RegisterGenericDecorator(
typeof(LoggingCommandDecorator<>),
typeof(ICommandHandler<>),
fromKey : "Handler",
toKey : "DecoratedHandler");
然后你就可以解决这个问题是这样的:
container.ResolveKeyed<ICommandHandler<CreateUserCommand>>("DecoratedHandler");
toKey
参数是可选的:
builder.RegisterGenericDecorator(
typeof(LoggingCommandDecorator<>),
typeof(ICommandHandler<>),
fromKey : "Handler");
然后你就可以解决这个问题是这样的:
container.Resolve<ICommandHandler<CreateUserCommand>>();
的toKey
是有用的,当你有中间装饰:
builder.RegisterGenericDecorator(
typeof(LoggingCommandDecorator<>),
typeof(ICommandHandler<>),
fromKey : "Original",
toKey : "Logging");
builder.RegisterGenericDecorator(
typeof(AuthorizationCommandDecorator<>),
typeof(ICommandHandler<>),
fromKey : "Logging");
在这种情况下,ICommandHandler<CreateUserCommand>
将LoggingCommandDecorator<>
和AuthorizationCommandDecorator<>
我提供了'toKey'参数和“DecoratedHandler”。当我离开这个时,everyhting工作。谢谢。 – Martijn
拆卸装饰所有的MVC逻辑,使用你的确切语法,我可以让装饰器按预期工作。指出你的问题可能在其他地方?!你能否看到如果你可以去掉所有的MVC逻辑并发布你仍然无法使装饰器工作的代码? – Ruskin