2016-06-13 51 views
1

這部分是尚未回答的同一問題的重複。看到這裏:How can I override a component registered in Castle Windsor?覆蓋溫莎城堡的組件註冊?哪個容器支持它?

因爲我不能評論或張貼任何現有問題的答案我再次創建這個問題,希望有人知道一個看似基本和簡單的問題的答案。

記住:

  1. 我不希望創建一個新的容器。
  2. 我不在乎容器是否不應該用於單元測試。
  3. 我不想使用派生容器。

如果溫莎城堡不能提供這個簡單的功能,你會推薦什麼其他的容器實現?

+0

我相信你的問題來自你的兩個「侷限」 - #1和#2。如果確實是* unit *測試,那麼一個容器就會按照你的方式進行 - 你有一塊*代碼在測試*,你的依賴應該都被嘲笑。如果您是*集成*測試,那麼使用容器可能是有意義的。但在這種情況下,*您應該使用與您的應用程序不同的容器*並嘲笑與測試無關的任何內容。 [重用容器](http://blog.ploeh.dk/2015/01/06/composition-root-reuse/)有點像爲一個不同的應用程序重用'.config'文件 - 爲什麼你會這樣? – NightOwl888

+1

@ NightOwl888:這是用於集成測試。新的容器沒有意義,例如我想測試一切,除了log4net組件。或者除了數據庫訪問層之外的一切。 如果我創建一個新的容器,我不測試真正的主題,但其他的東西不是重點。容器映射代碼的複製/粘貼也不是最佳實踐(經常見到)。 –

+0

[我如何覆蓋Castle Windsor中註冊的組件?](http://stackoverflow.com/questions/1687574/how-can-i-override-a-component-registered-in-castle-windsor) –

回答

0

回答問題的第二部分 - 哪些容器支持註冊覆蓋。

Ninject

請參閱綁定()/取消綁定()方法。

我也試過Autofac,但看起來註冊在被構建後變成凍結。所以似乎Autofac可能也不可能。

1

我不知道其他容器,但卡斯特,所以我的答案是關於城堡。如果你想替換你能做的就是寫一個擴展方法給IWindsorContainer,它將刪除然後添加。

但我認爲你應該重新考慮了一下你的設計:

  1. 爲什麼你的類需要容器的直接訪問,並嘗試通過自己從中化解?
  2. 爲什麼需要更改測試代碼的源代碼?如果根據SOLID編寫乾淨的依賴注入代碼,您的測試將真正「神奇地」流動。

您能否介紹一下關於設計和相關課程的更多內容?

1

溫莎與「最後登記獲勝」的會議合作。但是,如果你沒有明確告訴它,這個組件將被覆蓋,它會拋出一個異常。因此,有3種方法可以允許覆蓋現有組件:

  1. 使用.IsDefault()註冊組件。這將覆蓋現有的註冊。
  2. 使用.IsFallback()註冊組件。這將允許組件在稍後覆蓋 。
  3. 使用組件的唯一名稱 - .named(「NewComponentName」)。

我個人比較喜歡。IsDefault()並在我的集成測試中使用這種簡寫擴展:

public static class WindsorContainerExtensions 
    {    
     public static void Override<TService>(this IWindsorContainer container, TService instance) where TService : class 
     { 
      container.Register(Component.For<TService>().Instance(instance).IsDefault()); 
     } 
    } 
+0

IsFallback和IsDefault看起來像是一種解決方案。關於它的壞處是你需要改變被測試的主題,那就是你需要以特定的方式註冊你的組件,以便以後測試它們。最終我使用了Ninject和綁定/取消綁定功能。溫莎似乎缺乏基本的功能,所以我不得不做出這個決定。 –

+0

您不需要更改正在測試的主題。 .IsDefault()用於單元測試,當你不想更換組件時。 – andree