То, как я это сделал - и я не говорю, правильно это или неправильно, - это иметь мой взгляд, а затем модель, которая применима к моему мнению.Эта модель имеет только то, что имеет отношение к моему мнению, включая аннотации данных и правила проверки.Контроллер содержит только логику для построения модели.У меня есть сервисный слой, который содержит всю бизнес-логику.Мои контроллеры называют мой уровень обслуживания.Кроме того, это мой уровень хранилища.
Мои доменные объекты размещаются отдельно (собственно, в их собственном проекте).У них есть свои собственные аннотации данных и правила проверки.Мой репозиторий проверяет объекты в моем домене перед сохранением их в базу данных.Поскольку каждый объект в моем домене наследуется от базового класса, в который встроена проверка, мой репозиторий является универсальным и проверяет все (и требует, чтобы он наследовал от базового класса).
Вы можете подумать, что наличие двух наборов моделейэто дублирование кода, и это в определенной степени.Но есть вполне разумные случаи, когда объект домена не подходит для представления.
В данном случае речь идет о работе с кредитными картами - мне нужно указать cvv при обработке платежа, но я не могу сохранить cvv (это штраф в размере 50 000 долларов США).Но я также хочу, чтобы вы могли редактировать свою кредитную карту - изменение адреса, имени или срока действия.Но вы не собираетесь давать мне номер или cvv при редактировании, и я, конечно, не собираюсь указывать номер вашей кредитной карты в виде простого текста на странице.В моем домене есть эти значения, необходимые для сохранения новой кредитной карты, потому что вы даете их мне, но моя модель редактирования даже не включает номер карты или cvv.
Еще одно преимущество для многих слоев состоит в том, что при архитектуреправильно, вы можете использовать structmap или другой IoC-контейнер и менять части без вреда для вашего приложения.
По моему мнению, код контроллера должен быть только кодом, нацеленным на представление.Покажите это, скройте это и т. Д. Уровень обслуживания должен содержать бизнес-логику для вашего приложения.Мне нравится иметь все это в одном месте, так что легко изменить или настроить бизнес-правило.Уровень хранилища должен быть относительно тупым, лишенным бизнес-логики, и только запрашивать ваши данные и возвращать ваши доменные объекты.Отделяя модели представлений от модели предметной области, вы получаете гораздо больше гибкости, когда речь идет о пользовательских правилах проверки.Это также означает, что вам не нужно помещать каждый фрагмент данных в представление в скрытых полях и перемещать их назад и вперед между клиентом и сервером (или перестраивать их на бэкэнде).Тогда ваша модель представления будет содержать только информацию, относящуюся к представлению, и ее можно настроить так, чтобы иметь логические значения для логики представления, подсчета или перечисления, чтобы само представление не было загромождено сложными логическими утверждениями, такими как
<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) &&
Model.SomeObject.SomeInt == 3 && ...) { %>
Хотя все кажется разложенным и чрезмерно многослойным, оно имеет целью быть таким образом спроектированным.Это идеально?на самом деле, нет.Но я предпочитаю это некоторым прошлым проектам вызова репозиториев из контроллера и смешивания бизнес-логики в контроллере, репозитории и модели.