簡體   English   中英

使用RegisterAssemblyTypes時如何在Autofac中注冊裝飾器?

[英]How to register decorators with Autofac when using RegisterAssemblyTypes?

這是我的代碼

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));
}

運行此代碼時,出現以下異常:

無法使用可用的服務和參數調用類型為'AspectDemo.Controllers.HomeController'的'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'構造函數:無法解析參數'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<>裝飾

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM