1

從這個問題依賴注入使用視圖模型

MVC3 - Should I design my Model to be tightly coupled to my View?

繼它是如何建議使用您的視圖的視圖模型,並有控制器MVC控制器動作填充視圖模型,我一直在嘗試Ninject.MVC並使用一些示例來爲存儲庫模式注入控制器所需的存儲庫。

喜歡這個

public RecipesController(IRepository<Member> memberRepository, IRepository<Course> courseRepository, IRepository<Cuisine> cuisineRepository, IRepository<Recipe> recipeRepository) { 
     this.memberRepository = memberRepository; 
     this.courseRepository = courseRepository; 
     this.cuisineRepository = cuisineRepository; 
     this.recipeRepository = recipeRepository; 
    } 

然後我用MVC腳手架,看看有什麼動作看起來像

public ActionResult Create() { 
     ViewBag.PossibleCuisines = cuisineRepository.All; 
     ViewBag.PossibleMembers = memberRepository.All; 
     ViewBag.PossibleCourses = courseRepository.All; 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Create(Recipe recipe) { 
     if (ModelState.IsValid) { 
      recipeRepository.InsertOrUpdate(recipe); 
      recipeRepository.Save(); 
      return RedirectToAction("Index"); 
     } else { 
      ViewBag.PossibleMembers = memberRepository.All; 
      ViewBag.PossibleCourses = courseRepository.All; 
      ViewBag.PossibleCuisines = cuisineRepository.All; 
      return View(); 
     } 
    } 

我有一個很難理解如何使用視圖模型接近控制器動作。

說我有這樣的RecipeViewModel:

public class RecipeViewModel { 
    public Recipe Recipe { get; set; } 
    public SelectList AuthorList { get; set; } 
    public SelectList CourseList { get; set; } 
    public SelectList CuisineList { get; set; } 

    public RecipeViewModel(Recipe recipe) { 
     Recipe = recipe; 
    } 
} 

,這是模型我的觀點會使用。我認爲Create()GET動作會首先創建這個視圖模型,並且必須創建一個新的Recipe對象傳遞給ViewModel的構造函數?並且可以通過使用諸如cuisineRepository.All的相關存儲庫來填充選擇列表(但是這似乎將在每個操作中重複),然後視圖模型被傳遞給視圖。

雖然CreateState()POST操作中的ModelState.IsValid如何處理這個視圖模型?

通過這樣做,我的控制器現在需要一個RecipeViewModel對象,它本身需要一個Recipe對象。

它是否也使用這些接口並讓Ninject處理剩下的接口?這是可取的嗎?

回答

3

首先在RecipeViewModel不應含有配方的對象,但在含成員,如:

public class RecipeViewModel { 
    public RecipeViewModel(IRepository<Course> courseRepository, IRepository<Cuisine> cuisineRepository, IRepository<Recipe> recipeRepository){ 
     this.courseRepository = courseRepository; 
     this.cuisineRepository = cuisineRepository; 
     this.recipeRepository = recipeRepository; 
    } 
    public string RecipeName { get; set; } 
    public IList<IngredientsViewModel> Ingredients { get; set;} 
    public SelectList AuthorList { get; set; } 
    public SelectList CourseList { get; set; } 
    public SelectList CuisineList { get; set; } 

    public static RecipeViewModel Build() 
    { 
     //Build up Select Lists here and return View model. 
    } 

} 

然後驗證屬性去視圖模型,使ModelState.IsValid工作:

public class RecipeViewModel { 
    [Required] 
    public string RecipeName { get; set; } 
    public IList<IngredientsViewModel> Ingredients { get; set;} 
    public SelectList AuthorList { get; set; } 
    public SelectList CourseList { get; set; } 
    public SelectList CuisineList { get; set; } 
} 

就我個人而言,我會重構您的控制器以從視圖中分離數據層。

public RecipesController(IRecipeService recipeService) { 
    this.recipeService = recipeService; 
} 

然後控制器的其餘部分看起來像:

public ActionResult Create() { 
    var recipeViewModel = new RecipeViewModel(); 
    recipeViewModel.Build(): 
    ViewBag.PossibleCuisines = recipeViewModel.CuisineList; 
    ViewBag.PossibleMembers = recipeViewModel.AuthorsList; 
    ViewBag.PossibleCourses = recipeViewModel.CourceList; 
    return View(); 
} 

[HttpPost] 
public ActionResult Create(RecipeViewModel recipe) { 
    if (ModelState.IsValid) { 
     _recipeService.Save(recipe) 
     return RedirectToAction("Index"); 
    } else { 
     return View(); 
    } 
} 

的IRecipeService然後不從視圖模型的域模型的映射(在這種情況下RecipeViewModel到配方),然後持續該域模型。

+0

謝謝你的回答,讓我走上正軌。具體模式3在這裏:http://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx – Pricey 2012-03-11 16:26:21

+1

這不會拋出一個「沒有無參數的構造函數定義爲這個對象「錯誤,當MVC ModelBinder嘗試在POST創建操作中旋轉」RecipeViewModel「的實例時?我以爲你會需要一個自定義模型綁定器,如下所示:http://stackoverflow.com/a/24166483/71906 – 2014-06-11 16:06:17