Asp.net-Mvc-3

如何減少對控制器的注入依賴項的數量

  • August 11, 2014

我正在使用 MVC3、Entity Framework v4.3 Code First 和 SimpleInjector。我有幾個看起來像這樣的簡單類:

public class SomeThing
{
   public int Id { get; set; }
   public string Name { get; set; }
}

我有另一個看起來像這樣的實體:

public class MainClass
{
   public int Id { get; set; }
   public string Name { get; set; }
   public virtual AThing AThingy { get; set; }
   public virtual BThing BThingy { get; set; }
   public virtual CThing CThingy { get; set; }
   public virtual DThing DThingy { get; set; }
   public virtual EThing EThingy { get; set; }
}

每個 Thingy(目前)都有自己的 Manager 類,如下所示:

public class SomeThingManager
{
   private readonly IMyRepository<SomeThing> MyRepository;

   public SomeThingManager(IMyRepository<SomeThing> myRepository)
   {
       MyRepository = myRepository;
   }
} 

因此,我的 MainController 如下:

public class MainController
{
   private readonly IMainManager MainManager;
   private readonly IAThingManager AThingManager;
   private readonly IBThingManager BThingManager;
   private readonly ICThingManager CThingManager;
   private readonly IDThingManager DThingManager;
   private readonly IEThingManager EThingManager;

   public MainController(IMainManager mainManager, IAThingManager aThingManager, IBThingManager bThingManager, ICThingManager cThingManager, IDThingManager dThingManager, IEThingManager eThingManager)
   {
       MainManager = mainManager;
       AThingManager = aThingManager;
       BThingManager = bThingManager;
       CThingManager = cThingManager;
       DThingManager = dThingManager;
       EThingManager = eThingManager;
   }

   ...various ActionMethods...
}

實際上,這個控制器中註入的依賴項是原來的兩倍。它聞起來臭臭的。當您還知道存在具有所有或大部分相同依賴項的 OtherController 時,氣味會更糟。我想重構它。

我已經對 DI 有足夠的了解,知道屬性注入和服務定位器不是好主意。

我無法拆分我的 MainController,因為它是一個單一的螢幕,需要通過點擊一個保存按鈕來顯示和編輯所有這些內容。換句話說,單個 post 操作方法可以保存所有內容(儘管我願意更改它,只要它仍然是單個 Save 按鈕)。這個螢幕是用 Knockoutjs 建構的,如果有影響的話,它會用 Ajax 文章保存。

我幽默地使用了環境上下文,但我並不肯定這是正確的方法。我也幽默地使用了注入 Facade。我也想知道我是否應該在這一點上實現一個命令架構。(以上所有內容不只是將氣味轉移到其他地方嗎?)

最後,也許獨立於上述三種方法,我是否應該使用一個具有顯式方法的 LookupManager,例如 GetAThings()、GetAThing(id)、GetBThings()、GetBThing(id) 等?(但是那個 LookupManager 需要注入幾個儲存庫,或者一種新型的儲存庫。)

除了我的想法之外,我的問題是,重申一下:重構此程式碼以減少注入依賴項的瘋狂數量的好方法是什麼?

使用命令架構是個好主意,因為這會將所有業務邏輯移出控制器,並允許您添加橫切關注點而無需更改程式碼。但是,這不會解決您的建構子過度注入問題。標準解決方案是將相關依賴項移動到聚合服務中。但是,我同意 Mark 的觀點,您應該看看unit of work pattern

您是否考慮過使用工作單元設計模式?關於什麼是工作單元,有一篇很棒的 MSDN文章。那篇文章的摘錄:

在某種程度上,您可以將工作單元視為轉儲所有事務處理程式碼的地方。工作單位的職責是:

  • 管理交易。
  • 對數據庫的插入、刪除和更新進行排序。
  • 防止重複更新。在 Unit of Work 對象的單一用法中,程式碼的不同部分可能會將同一個 Invoice

對象標記為已更改,但 Unit of Work 類只會

向數據庫發出單個 UPDATE 命令。

使用工作單元模式的價值在於將其餘程式碼從這些問題中解放出來,這樣您就可以專注於業務邏輯。

有幾篇關於這個的部落格文章,但我發現的最好的一篇關於如何實現它是here。還有一些其他的已經從這個網站herehere中提到過。

最後,也許獨立於上述三種方法,我是否應該使用一個具有顯式方法的 LookupManager,例如 GetAThings()、GetAThing(id)、GetBThings()、GetBThing(id) 等?(但是那個 LookupManager 需要注入幾個儲存庫,或者一種新型的儲存庫。)

工作單元將能夠處理所有這些,特別是如果您能夠為大多數數據庫處理需求實現通用儲存庫。您的標籤提到您正在使用 Entity Framework 4.3 對嗎?

希望這可以幫助!

引用自:https://stackoverflow.com/questions/12046690