1

Исходя из этого вопросаDependency Injection для действий контроллера MVC, использующих модель просмотра

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

о том, как это рекомендуется использовать модель представления для ваших взглядов и имеет контроллер заселить модель представления, я были опробованы 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 сначала создало бы эту модель представления и было бы необходимо создать новый объект рецепта для перехода к конструктору ViewModel? и списки выбора могут быть заполнены с помощью соответствующего репозитория, такого как cuisineRepository.All (но это похоже, что он будет дублироваться в каждом действии), а затем модель представления передается в представление.

Как работает ModelState.IsValid в действии Create() POST для этой модели представления?

Таким образом, мой контроллер теперь ожидает объект RecipeViewModel, который сам нуждается в объекте Рецепт.

Должны ли они использовать интерфейсы для них тоже и иметь ручку 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. 
    } 

} 

Затем проверки атрибутов идут на ViewModel, чтобы сделать 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

+1

Не вызывает ли это «No parameterless constructor», определенный для этот объект ", когда MVC ModelBinder пытается развернуть экземпляр' RecipeViewModel' в действии POST Create? Я думал, вам понадобится настраиваемое связующее устройство: http://stackoverflow.com/a/24166483/71906 –

Смежные вопросы