2016-01-20 39 views
1

這是我的代碼使用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個裝飾器。

+0

拆卸裝飾所有的MVC邏輯,使用你的確切語法,我可以讓裝飾器按預期工作。指出你的問題可能在其他地方?!你能否看到如果你可以去掉所有的MVC邏輯併發布你仍然無法使裝飾器工作的代碼? – Ruskin

回答

1

當您使用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<>

+0

我提供了'toKey'參數和「DecoratedHandler」。當我離開這個時,everyhting工作。謝謝。 – Martijn

相關問題