MVC 3 - контроллеры и ViewModels-что должно содержать большую часть бизнес-логики?
В настоящее время в моем приложении, использующем unit of work pattern и generic repository, все мои контроллеры содержат всю бизнес-логику. Я нахожусь в процессе перехода на использование ViewModels вместо прямой модели.
Хотя это хорошая идея,теперь возникает вопрос, который может значительно разделить мою бизнес-логику в контроллерах. Для контроллеров и моделей просмотра, которые должны содержать большую часть бизнес-логики?
Я попробовал несколько способов, чтобы получить мой ViewModels практически содержат всю бизнес-логику. Однако у меня должен быть аргумент в конструкторе моего ViewModel, который занимает единицу работы. Это хорошая идея?
Мой кодовый запах говорит мне, что это так. Однако я просто немного беспокоюсь, как это будет согласовано с контроллерами, которые выполняют действия, которые не нуждаются в ViewModels. Проще говоря, действия, которые не требуют передачи модели/ViewModel в представление; этот случай происходит на действиях, которые делают перенаправление на другие действия. Который значит, моя бизнес-логика может либо остаться в этом действии, либо я могу разделить эту бизнес-логику на функции.
Какова здесь наилучшая практика?
4 ответа:
Для контроллеров и моделей просмотра, которые должны содержать большую часть бизнес-логики?
Ничего из этого.
Я попробовал несколько способов заставить мои ViewModels практически содержать всю бизнес-логику. Однако у меня должен быть аргумент в конструкторе моего ViewModel, который занимает единицу работы. Это хорошая идея?Имхо, это очень плохая идея. Прежде всего, вы нарушаете несколько твердых принципов. Объединение всего кода в модель представления это затрудняет проверку. Что делать, если вы хотите использовать часть бизнес-логики в другом представлении? Вы дублируете этот код?
Какова здесь наилучшая практика?
Давайте сначала вернемся к шаблону MVC. Это довольно широкое определение, но знание его должно дать вам ощущение того, что вы должны поместить куда.
Проблема с этой структурой заключается в том, что довольно легко "просочить" определенную информацию слоя в другие части шаблона. Поэтому Microsoft представила ViewModels в их реализации MVC. Таким образом, мы можем удалить всю логику визуализации из представлений и поместить ее в модель представления. Вместо того, чтобы делать это в вашем представлении:
"модель" в MVC-это действительно все, что используется для объединения данных. Это могут быть веб-сервисы, бизнес-слой, репозитории и т.д.
Представление-это весь код, который генерирует HTML (поскольку мы говорим о web).
Контроллер следует рассматривать как связующее звено между моделью и представлением. Следовательно, он должен взять информацию из модели и преобразовать ее во что-то полезное для представления.
Вместо этого вы помещаете этот код в ViewModel и просто вызываете<span>@(model.Age == 0 ? "n/a" : model.Age)</span>
@model.Age
. Таким образом, вам не придется дублировать этот код во всех представлениях, использующих вашу модель представления.Ответ на ваш вопрос о ViewModel заключается в том, что он должен содержать только логику, которая используется для визуализации информация из "модели" исправна.
Что касается контроллера, я бы тоже не стал вкладывать в него бизнес-логику. Прежде всего, это очень затрудняет проверку вашей логики. Затем вы добавляете к нему больше ответственности (и тем самым нарушаете SRP). Единственная логика, которая допустима в контроллере, - это взять информацию из ViewModel и преобразовать ее во что-то полезное для "модели" и наоборот.Надеюсь, что ответ на ваш вопрос.
Обновить
Я бы создал отдельный проект и добавил в него классы. Затем просто добавьте ссылку из вашего webproject и вызовите эти классы в контроллерах.
Я бы также начал использовать инверсию контейнера управления, чтобы получить эти зависимости, созданные для меня автоматически.
Autofac может как обнаружить ваши сервисы для вас (нулевая конфигурация), так и внедриться в MVC.
Следовать шаблону разделенного интерфейса создайте следующие проекты:
- ваш проект.BusinessLayer
- ваш проект.Деловой человек.Спецификация
- ваш проект.Mvc
Проект "спецификация" может быть использован для облегчения тестирования и переключения реализации (может быть только несколько классов и не обязательно весь бизнес-уровень). Читайте дальше "Отдельный Шаблон Интерфейса"
Я не могу сказать, что мой подход является лучшей практикой, но я предпочитаю помещать любую бизнес-логику в отдельный "сервисный" слой.
Я склонен использовать ViewModel только для хранения свойств, необходимых для конкретного представления. Если в ViewModel есть какие-либо методы, они, скорее всего, просто извлекают коллекции, связанные с этим представлением.
Я поддерживаю легкий вес своих контроллеров, пытаясь максимально ограничить их проверку и перенаправление / отображение представлений.
Так что если у меня есть любая сложная логика, у меня будет вызов действия контроллера к отдельной службе только для обработки этой логики. Таким образом, логика изолирована, что облегчает ее тестирование, поскольку больше нет необходимости создавать контроллер или ViewModel для ее тестирования. Кроме того, проще повторно использовать сервис, чем разбирать ViewModel.
Надеюсь, это поможет. Удачи.
Model-View-View Model (MVVM) - это шаблон проектирования для построения пользовательских интерфейсов. Модель представления - это чисто кодовое представление данных и операций в пользовательском интерфейсе. Таким образом, он должен содержать логику, связанную с этим пользовательским интерфейсом.
Например:
Если вы реализуете редактор списков, ваша модель представления будет представлять собой объект, содержащий список элементов и предоставляющий методы для добавления и удаления элементов.
Из Википедии:
ViewModel: ViewModel - это " модель представления" это означает, что он является абстракция представления, которая также служит для связывания данных между Вид и модель. Это можно рассматривать как специализированный аспект того, что был бы контроллер (в шаблоне MVC), который действует как данные связующее устройство / преобразователь, преобразующий информацию модели в информацию вида и передает команды из вида в модель. модель представления предоставляет общедоступные свойства, команды и абстракции. модель представления было уподоблено концептуальному состоянию данных в противоположность к реальное состояние данных в модели.[7]
Ваш контроллер вызывает UoW, чтобы получить данные, необходимые для построения вашей viewmodel. вы можете назвать более чем 1 метод Ву
Затем вы передаете все необходимые данные в конструктор viewmodel. (передавая uow для де модель представления звучит как очень плохая)
Если вам нужна какая-то сложная "логика" на вашем контроллере, вызывающая множество методов из UoW и т. д., Вы должны рассмотреть возможность создания другого репозитория или слоя только бизнес-логики, который выполняет всю тяжелую работу, и вы вызываете его из ваш контроллер, как
SomeClass something = Uow.BLGoodName.DoSomeFancyStuff(params ..) ViewData.model = new ControllerActionViewModel(something); Return View();