我正在Visual Studio .NET 4.0中開發Windows應用程序,我正在使用MVP模式,並試圖在整個應用程序中學習並應用依賴注入原則。但我無法理解如何最好地處理特定情況。對於長時間的解釋,我提前道歉,但我不知道我是否可以具體說明其他方面。當許多相似但不同的類需要許多相似但獨特的依賴關係時,我該如何最好地實現依賴注入?
該應用程序是一個通用的記錄應用程序,用於許多不同類型的記錄,其中一些相互關聯,其中一些與其他記錄無關。我們使用的每種不同的記錄類型在應用程序中構成了一個獨特的「特徵」。因此,應用程序的啓動屏幕本質上是一個交換機,可以從中選擇要導航到的功能。
當他們做出選擇時,該特徵的窗口(視圖)打開,並且從該窗口他們可以執行與該特徵相關的各種操作。大多數功能(例如客戶,訂單)具有用戶可執行的一些常用操作(創建新記錄,打開現有記錄,保存更改,打印等)。然而,某些功能具有特定的操作(例如特定於「訂單」功能的驗證操作)。我的問題在於弄清楚如何在每個功能中執行操作。
由於我使用MVP,功能窗口有一個演示者,當用戶啓動該功能的任何操作時將會響應。但是因爲我想遵循單一責任原則,所以我不希望演示者成爲上帝類,並且實際上知道如何創建記錄,保存,打印等。所以我的想法是定義單獨的類來處理每個操作,如使用.Create()方法實現ICreateOrders實現,使用.Save()方法實現ISaveOrders實現等等。爲了給它們起個名字,我會稱它們爲「解析器」,因爲它們實際上解析了請求要發生這種行動。其中一些常見的解析器可能具有基本實現(例如基礎FeatureSave類),因爲大部分代碼在各個特性上都是相似的,但如果需要,每個特性都需要具有特定的實現。這種方法引發了一些問題。
首先,我希望這些操作能夠從應用程序中的其他位置啓動,而不僅僅是該功能的窗口。例如,我不希望從訂單功能窗口中打開訂單記錄,而是希望能夠從客戶功能中選擇「查看訂單」,並讓該客戶的訂單記錄自動打開並顯示。爲了實現代碼重用,我希望使用相同的IOpenOrders實現來完成這項工作,而不管應用中從何處開始請求。因此,只需在訂單窗口的演示者中嵌入所需的解析器似乎不是一種選擇。
所以我的想法是創建一個FeatureService類,它可以容納Feature對象的集合。在應用程序啓動時,我會從數據庫中獲取對登錄用戶有效的所有功能的列表,然後遍歷該列表併爲每個列表創建一個Feature對象,並將其添加到FeatureService的集合中。然後,當我需要從另一個功能啓動一個操作時,我可以通過將FeatureService對象注入到源類中,從中獲取目標功能,然後使用它執行操作來實現該操作。但我不希望Feature類成爲上帝類,所以這隻需將所有單個解析器從訂單展示器移動到Feature類。
但是,要發生這種情況,Feature對象必須注入所有可能需要的解析器,而不知道用戶是否執行這些操作。對於一些更復雜的功能,這可能是20或30個不同的解析器被注入,這當然看起來像構造函數注入濫用。雖然這使得Feature對象不能成爲上帝類,因爲它只是將每個操作傳遞給它的注入解析器,這似乎是錯誤的。當對象變成這樣的「上帝協調員」時,這是否正確?
我的另一個問題是關於這些對象的體積。對於某些客戶,可能會有50個或更多的獨立功能可用(隨着時間的推移,更多功能將無疑)。因此,當我在啓動時創建這些Feature對象並且我的容器將所有這些解析器依賴項注入到每個對象中時,我創建了數百個對象(例如,每個功能的40個功能X 20個解析器),無論我是否訪問某些功能或不。一個典型的用戶會話可能只涉及到幾個功能,所以在啓動時創建如此多的對象似乎很浪費。我可以放棄,只是讓Feature對象在內部執行ServiceLocation來獲得它的解析器,但如果有更好的方法,我想使用它。
我不知道該從哪裏出發。我試圖尋找並找到關於這方面的例子和信息,但是我不知道我是否知道足夠的知道要搜索什麼。任何人可以提供的指導或見解將不勝感激。
感謝您的建議和時間來回答這個問題。我會試試看看它是如何工作的。 – bjohnson