我正在處理一個大型的傳統C#應用程序,並且分配給我的任務是刪除靜態工廠類ServiceLocator.GetObject<T>()
的所有用法,並全部替換爲構造函數注入的依賴項。在擴展方法中需要工廠類
大部分情況下,這很簡單,但是在應用程序代碼庫中有大約50個情況,這有點棘手。例如,Servicelocator
用於靜態類或擴展方法,甚至是WPF MarkupExtension !.
例如,如果您遇到像這樣的代碼片段,您會怎麼做? (除了哭)
public static class MyExtensions
{
private static ISingletonServiceOne _ServiceOne = null;
private static ISingletonServiceTwo _ServiceTwo = null; // etc ...
public static SummaryHeader GetBannerSummary(this IModel rfq, object requester)
{
Guard.ArgumentNotNull(rfq, "rfq");
Guard.ArgumentNotNull(requester, "requester");
if (_ServiceOne == null)
{
_ServiceOne = ServiceLocator.GetService<ISingletonServiceOne>(requester);
Guard.ArgumentNotNull(_ServiceOne, "_ServiceOne");
}
return _ServiceOne.GetBannerSummary(rfq);
}
在上述的ServiceLocator.GetObject()方法已經以擴展方法被用在IModel來定位一個單註冊的服務和關於使用IModel執行的方法。
的問題是:
- 是否有任何模式/做法,以避免這樣的事情 - 在一個靜態類,值轉換器或擴展方法
- 需要一個DI容器是否有任何模式/在DI中處理循環依賴的實踐?
- 如果在良好的代碼和交付時間之間存在折衷,那麼您會在上面做什麼?
我想移動GetBannerSummary()方法進行擴展,只有IModel在這種情況下,但是,(不要笑)也有在ValueConverters(WPF)和MarkupExtensions所使用的相同的服務定位的情況下, :0
您的意見/建議表示讚賞
嗨馬克,感謝您的答案 - 我編輯了外部請求者作爲ServiceLocator的實現實際上沒有做任何事情!同意你的預後。這是一個相當令人震驚的意大利麪條網絡,我在這裏處理,所以任何建議打破它歡迎:) –
嗨安德魯,不客氣 - 我們都必須經歷它!我認爲你所做的一切都是正確的,但我在靜力學,擴展等方面看不到有關ServiceLocator的方法。如果您已將所有依賴關係保持爲模塊化,那麼這是一個必要的弊端。 –
大的重構正在進行中,因爲在另一個項目中需要重新使用大塊代碼作爲棱鏡「模塊」。當我聽到這個消息時,我的反應是「大聲笑」。無論如何,在ServiceLocator的120個用例中,我已經下降到了60個。我認爲我可以調整更多,但是如果沒有「易用」解決方案,可能會留下一些。非常感謝 –