2012-12-26 118 views
8

偶爾我發現自己處於需要解決某項服務的情況,只有在滿足某些條件的情況下。例如,用戶可能選擇發送電子郵件或短信通知。我想懶加載電子郵件或短信服務取決於用戶選擇什麼,這樣我就不必加載他們和浪費資源(如果有,例如,用戶有10個選項......? )。溫莎城堡延遲加載服務

我遇到的問題是在我的引導代碼之外使用容器(我不希望我的代碼依賴於容器)。我似乎無法找到一種解決方法來使用容器進行延遲加載服務(除非我手動創建所需服務並手動執行所有DI)。這是一種規則可以彎曲還是有更好的方式?

回答

5

如果您使用的是Castle Windsor 3.0或更新版本,則可以使用懶惰解析。

請參閱What's new in Windsor 3 for more details

註冊過程改變了一點(新組件加載程序必須註冊)。

之後,您只是一如既往地註冊組件,但解決依賴關係爲Lazy<T>而不是T。在您不會訪問Lazy<T>.Value屬性之前,依賴關係將不會被解析,因此您可以傳遞幾個懶惰評估的對象並只訪問您需要的對象。

如果你有更多的選擇給用戶,也許你應該考慮創建某種抽象工廠界面。然後,您只需註冊並解決此工廠問題,而工廠本身將爲發送通知(無論是郵件還是短信或任何其他選項)創建適當的服務。工廠的實施可以用手工編碼,或者Castle Windsor可以用這個編碼(我認爲從3.0版本開始)。

通常當我使用這樣的工廠時,我手工實現它,並通過容器作爲依賴項,所以只有工廠實現取決於我的容器。

1

一般來說,你可以用Typed Factory Facility來做到這一點。

簡而言之,當你解決了使用這些服務,而不是給它一個電子郵件或短信服務的組件,你給它一個工廠,可以創建它們(這是由您定義,而不對引用容器)

該設施將負責「實施」您的工廠(從您創建的界面),因此幾乎沒有什麼可做的。

+0

如果什麼我的每個服務都有其獨特的依賴關係。例如,短信服務有3個獨特的依賴關係,電子郵件服務有4個獨特的依賴關係,等等。我是否只需要向工廠注入20個(或多個)依賴關係?偉大的迴應btw。 – orourkedd

+0

工廠由城堡實施。您只需像往常一樣配置您的服務。 –

2

只是一個例子,以簡化(基於馬爾辛 - 德普圖拉答案)

// activate Lazy initialization feature for all Components 
.Register(Component.For<ILazyComponentLoader>().ImplementedBy<LazyOfTComponentLoader>())  
// register rest of component(s) 
.Register(Component.For<IIssueRepository>().ImplementedBy<IssueRepository>()) 
. .... 

決心懶洋洋地(屬性注入)

public Lazy<IIssueRepository> IssueRepository { get; set; } 
IssueRepository.Value.GetLastIssue(); 

決心正常(屬性注入)

public IIssueRepository IssueRepository { get; set; } 
IssueRepository.GetLastIssue();