Asp.net-Mvc

模型需要注入依賴時的模型(ViewModel)綁定

  • June 11, 2014

我在 ASP.Net MVC 應用程序中使用 Ninject 進行依賴注入(這是我第一個使用 Ninject 或 DI 的項目)。

我選擇使用 Model-View-ViewModel 模式。視圖模型將提供我將綁定到實際視圖的所有屬性,但還需要訪問數據庫以獲取數據列表等內容。例如:

public class CreateGetIncidentViewModel
{

   private IDBContext _dbContext = null;

   [Required]
   public EmployeeType EmployeeType { get; set; }


   [Required]
   [StringLength(50)]
   public string Department { get; set; }

   /
   public IEnumerable<SelectListItem> GetEmployeeTypeSelectList()
   {
       // Simplified for brevity
       var employeeTypes = _dbContext.EmployeTypes.Where().... // Go select the employee types

       var employeeTypeSelectList = new List<SelectListItem>();

       foreach(var employeeType in employeeTypes){
           employeeTypeSelectList.Add(new SelectListItem(){
               // Set select list properties
           });
       }           

       return employeeTypeSelectList;
   }
}

我的問題是:

  • IDBContext 是 Ninject 中的一個註冊依賴項。通過實例​​化直接訪問具體類型是不行的。
  • 我必須以某種方式將該依賴項注入到此類中,或者以某種方式通過其他已經解決了依賴項的類來訪問該依賴項。

鑑於我的 ViewModel 經常通過模型綁定由 ASP.Net MVC 自動補充,我如何將我的依賴項添加到我的 ViewModel 中?

我經歷了多種方式,但它們看起來都很髒。我可以(但不想)

  • 實現服務定位器模式只是簡單地從 ViewModel 中解決我的 IDBContext 依賴關係。
  • 在我的控制器中解析 IDBContext 並在手動建構 ViewMode 時將其傳遞到我的 ViewModel 中,即new CreateGetIncidentViewModel(dbContext);
    • 這並不能解決視圖模型被 MVC 水合的問題,儘管當模型被發佈到一個動作時

建議?

鑑於我的 ViewModel 經常通過模型綁定由 ASP.Net MVC 自動補充,我如何將我的依賴項添加到我的 ViewModel 中?

您可以編寫一個自定義模型綁定器,將依賴項注入到視圖模型建構子中。

話雖這麼說,恕我直言,在 ASP.NET MVC 中使用 MVVM 模式從一開始就是錯誤的方法,如果你這樣做,你必須準備好承受很多痛苦。你準備好了嗎?

如果沒有,這是我向您推薦的:

Controller -> Domain model -> View model -> View

在這種模式中,您讓控制器知道儲存庫(DbContext- 由您的 DI 框架自動注入其中)。

流程一:

  1. 控制器接收使用者的請求
  2. 控制器使用儲存庫查詢一個或多個域模型
  3. 控制器使用映射層將這些域模型映射到視圖模型
  4. 控制器將此(單個)視圖模型傳遞給視圖以進行渲染

流程 2:

  1. 控制器接收來自視圖的請求(例如表單送出)
  2. 模型綁定器自動將請求主體綁定到您的控制器操作作為參數的單個視圖模型
  3. 控制器正在使用映射層將此視圖模型映射到一個或多個域模型
  4. 控制器正在使用儲存庫來更新這些域模型。

在此範例中,視圖模型不了解任何儲存庫或數據訪問或 DbContexts。視圖模型是視圖的表示。域模型和視圖之間的映射是控制器的職責(可以委託給映射層)。我個人AutoMapper用來執行我的域模型和視圖模型之間的映射。

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