2015-04-14 41 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