2015-04-14 105 views
3

我想装饰使用城堡windsor我的命令处理程序,但似乎我的注册是不正确的,因为该类没有装饰。注册城堡windsor中的通用装饰器?

我有以下的安装程序:

internal class CommandsInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(
      Component.For<IDbConnection>() 
       .UsingFactoryMethod(() => ConnectionHelper.GetOpenDbConnection(Connection.DatabaseName.ReedOnline)) 
       .LifestylePerWebRequest()); 

     container.Register(
      Classes 
       .FromAssemblyContaining<EcruiterCommands>() 
       .Where(t => t.Name.EndsWith("Commands")) 
       .WithService 
       .AllInterfaces().LifestylePerWebRequest()); 

     container.Register(
      Classes 
       .FromAssemblyContaining<EcruiterCommands>() 
       .Where(t => t.Name.EndsWith("CommandHandler")) 
       .WithService.AllInterfaces() 
       .LifestylePerWebRequest()); 

     container.Register(Component.For(typeof (ICommandHandler<>)) 
      .ImplementedBy(typeof (TransactionCommandHandlerDecorator<>)) 
      .IsDefault() 
      .LifestylePerWebRequest()); 

     container.Register(Component.For(typeof (ICommandHandler<>)) 
      .ImplementedBy(typeof (ExceptionHandlingCommandHandlerDecorator<>)) 
      .IsDefault() 
      .LifestylePerWebRequest());    
    } 
} 

,这是我的装饰:

namespace TempSearch.Ioc.Decorators.CommandHandlers 
{ 
    public class TransactionCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> 
    { 
     private readonly ICommandHandler<TCommand> decorated; 

     public TransactionCommandHandlerDecorator(ICommandHandler<TCommand> decorated) 
     { 
      this.decorated = decorated; 
     } 

     public void Handle(TCommand command) 
     { 
      using (var scope = new TransactionScope()) 
      { 
       decorated.Handle(command); 
       scope.Complete(); 
      } 
     } 
    } 
} 

另外我想知道如果我的装修应该活在组合物根或组装他们正在装修的班级。现在,我让他们搬到了组成根为温莎城堡试图与其他类一起注册我的装饰,我会得到错误:

Component TempSearch.Command.Data.Decorators.TransactionCommandHandlerDecorator`1 could not be registered. 
There is already a component with that name. 
Did you want to modify the existing component instead? 
If not, make sure you specify a unique name. 
+1

“_... am am difficult_”会有什么困难?也试着坚持每个帖子一个问题。 –

+0

@PatrickQuirk是对的。我试着在实现编辑之前回答关于装饰器的问题。请回滚并打开另一个问题,而不是 – samy

+1

我在这里打开另一个问题:http://stackoverflow.com/questions/29627510/castle-windsor-instances-are-registered-as-singleton-even-though-explicitly-decl – Xerxes

回答

1

首先,关于“已经被注册”的错误,你是注册您的组件两次

container.Register(
    Classes 
     .FromAssemblyContaining<EcruiterCommands>() 
     .BasedOn(typeof (ICommandHandler<>)) 
     .WithService.AllInterfaces() 
     .LifestylePerWebRequest()); 

这个注册是基于ICommandHandler<>所有类,所以TransactionCommandHandlerDecorator已注册

关于你要去的装饰图案,我会用它实现改为城堡的interceptors。我发现装饰者模式是在Castle中做not very easy;这个答案相当老旧,Castle从那时起就改变了,所以我可能是错的,但拦截器是你想要的。

+0

我试过明确地只绑定那些在最后有“CommandHandler”的实例,但它仍然不起作用,有什么想法? – Xerxes

+0

除了我已经写了不多。你可以看看订单特定的注册,看看它是否有助于设置装饰,但我会去拦截器 – samy

+0

@Xerxes:如果你阅读Krzysztof Kozmic在这里的Stackoverflow的答案关于在温莎城堡应用通用装饰器,你会发现Castle支持这种有限的Krzysztof建议,而不是使用拦截。这当然不是一个非常令人满意的答案,因为拦截会强制你的代码对拦截库有依赖性,并导致代码的可读性更差,更不易维护。 – Steven