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