2015-03-19 88 views
2

我試圖使用Castle.Windsor(3.2.0.0)convention based registration,但似乎無法弄清楚如何註冊在特定命名空間中實現特定接口只有的類。如何通過接口和命名空間與Windsor註冊類?

例如我真的希望能夠寫的是這樣的:

container.Register(Classes.FromThisAssembly() 
          .InNamespace("MyApp.EventHandlers") 
          .BasedOn(typeof(IHandlesEvent<>)) 
          .WithServiceAllInterfaces() 

但我得到的似乎暗示着這是什麼警告纔會真正做的是註冊在EventHandlers命名空間中的一切,那麼一切都在目前的組件實施IHandlesEvent<>

如果我運行應用程序,這似乎確實會發生什麼。我不希望所有實現這個接口的東西都被註冊(例如,一些實現類是Sagas,需要手動跟蹤),而且我並不想讓那個名字空間中的所有東西都註冊。

我真的不想單獨註冊事件處理程序,但我無法從Windsor文檔中看到如何按照約定執行我需要的操作。可能嗎?

+0

我從來沒有注意到這一點,訴有趣和令人驚訝的行爲。我原以爲這個構造會在內部解析爲一個過濾器列表,但它甚至不會像這是最終結果 – samy 2015-03-19 12:14:05

回答

2

我很驚訝,但我可以觀察城堡3.2的行爲。 BasedOn推警告說,這將重新初始化登記:這裏是我的示例代碼:

namespace WindsorTest 
{ 
    public interface IHandlesEvent {} 

    public interface IDontWantToBeRegistered {} 

    namespace Select 
    { 
     public class SelectClass : IHandlesEvent { } 
     public class DontRegisterMe : IDontWantToBeRegistered { } 
    } 

    namespace DontSelect 
    { 
     public class DontSelectClass: IHandlesEvent {} 
    } 


    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      var container = new WindsorContainer(); 
      container.Register(Classes.FromThisAssembly() 
       .InNamespace("WindsorTest.Select") 
       .BasedOn<IHandlesEvent>() 
       .WithServiceAllInterfaces() 
       ); 
      foreach (var handler in container.ResolveAll<IHandlesEvent>()) 
      { 
       Console.WriteLine(handler.GetType().Name); 
      } 

      foreach (var handler in container.ResolveAll<IDontWantToBeRegistered>()) 
      { 
       Console.WriteLine(handler.GetType().Name); 
      } 
      Console.ReadLine(); 
     } 
    } 
} 

跑時,它輸出DontSelectClass

但是,我發現了一種方法,從您的註冊基類開始,然後使用命名空間對其進行優化。只用:

container.Register(Classes.FromThisAssembly() 
    .BasedOn<IHandlesEvent>() 
    .If(t => t.Namespace == "WindsorTest.Select") 
    .WithServiceAllInterfaces() 
    );