2008-09-17 88 views
9

我有一個對象實現了在Windsor容器中註冊的IDisposable,我想處理它,因此它的Dispose方法被調用,並且下一次調用Resolve時它會提取一個新的實例。Windsor Container:如何強制處理一個對象?

是否

container.Release(obj); 

自動調用Dispose()馬上?或者,我需要做的

obj.Dispose(); 
container.Release(obj); 

上無法找到文檔中任何事情究竟是什麼版本還

編輯: 見我的回答如下的測試我跑的結果。現在問題變成了,我該如何強制容器釋放具有單例生命週期的組件實例?這隻需要在一個地方完成,寫一個自定義的生命週期似乎太重量級了,是否沒有建立它的方式?

回答

10

這是我認爲人們沒有真正意識到與溫莎容器中工作時的 - 尤其是經常奇怪行爲一次性短暫的組件由容器扶住爲內核的一生,直到它的處置除非你釋放他們自己 - 雖然它記錄 - 看看here - 但快速報價:

微內核有一個可以連接起來,實現一些 路由處置組件可插拔的發行政策。微內核帶有三個IReleasePolicy實現:

  • AllComponentsReleasePolicy:跟蹤所有部件在微內核的情況下處置
  • LifecycledComponentsReleasePolicy執行正確的處置:只跟蹤具有相關
  • NoTrackingReleasePolicy的停止使用生命週期的組件:不執行任何跟蹤

您還可以使用接口IReleasePolicy實現您自己的發佈策略。

,你可能會發現更容易是政策改變爲NoTrackingReleasePolicy,然後處理處置自己 - 這是潛在的風險爲好,但如果你的生活方式在很大程度上是短暫的(或者,如果當您的容器配置無論如何,你的應用程序即將關閉),這可能不是什麼大不了的事情。不過請記住,任何已經被單體注入的組件都會有一個引用,所以你最終可能會試圖「刷新」你的單例 - 這似乎是一個不好的習慣,我想知道是否可以避免必須首先通過改進應用程序放在一起的方式來做到這一點。其他方法是使用自己的解除執行來構建自定義生命週期(因此釋放單例實際上會處理組件,就像暫時的生命週期一樣)。

或者,另一種方法是使用單件生活方式在您的服務中註冊一個服務的裝飾器,但是您的實際底層服務以瞬態生活方式在容器中註冊 - 那麼當您需要刷新組件時,只需處理暫時的底層組件被裝飾者持有,並用一個新解決的實例代替它(使用組件鍵來解決它,而不是服務,以避免獲得裝飾器) - 這可以避免與其他單件服務(未被刷新「)從持有過時的服務中解放出來,使它們無法使用,但確實需要一些鑄造等來使其工作。

+0

我有一個類似的問題,我非常喜歡裝飾者的概念。不錯的一個... – 2009-11-09 19:43:40

3

這取決於您將其添加到容器時指定的組件的生活方式。

你會使用Release()如果生活方式是Pooled。這會將組件重新放回池中以供下次檢索(對象未被破壞,因此處置會很糟糕)

如果生活方式是暫時的,則在獲取組件時會創建一個新對象。在這種情況下,處理由您決定,您不需要撥打發布

如果生活方式爲線程,則每個線程使用相同的組件,而不是銷燬。

如果生活方式是單身人士,只有一個組件被創建並且沒有被銷燬。

很可能,您正在使用瞬態組件? (如果您擔心及時它們的處置) 在這種情況下,只需用用包裹它,你設置(或致電某處處置自己)

using(ISomeService service = container.Resolve<ISomeService>()) 
{ 
// Do stuff here 
// service.Dispose is automatically called 
} 

編輯 - 是的,爲了「刷新」或者處理並重新創建你的單例,你需要銷燬容器或者寫一個自定義的生命週期。做一個自定義的生命週期並不是那麼困難,並且保持邏輯在一個地方這樣做。

+0

其實我正在做singletons,但想強制它偶爾重新生成組件。 – 2008-09-17 17:30:19

1

好的,所以我一直在運行測試,看起來像Container.Release()會隱含導致IDisposable的方法只有在生活方式是瞬態時纔會執行(這可能不完全正確,但要指出的是它不會「如果生活方式是單身的話)。

現在,如果你調用Container.Dispose()它會調用一次性方法還,但不幸的是它會處理整個內核,你將不得不對所有組件添加回去:

var container = new WindsorContainer(); 
container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton); 
var obj = container.Resolve<MyDisposable>(); // Create a new instance of MyDisposable 
obj.DoSomething(); 
var obj2 = container.Resolve<MyDisposable>(); // Returns the same instance as obj 
obj2.DoSomething(); 
container.Dispose(); // Will call the Disposable method of obj 
// Now the components need to be added back in 
container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton); 
var obj3 = container.Resolve<MyDisposable>(); // Create a new instance of MyDisposable 

幸運在我的情況,我可以只需放下所有組件,我就可以很容易地恢復它們。然而,這是次優的。