Подтвердить что ты не робот

Должна ли модель просмотра возвращаемого уровня для приложения MVC?

Предположим, что у вас есть проект ASP.NET MVC и вы используете сервисный уровень, например, в этом руководстве для менеджера контактов на сайте asp.net: http://www.asp.net/mvc/tutorials/iteration-4-make-the-application-loosely-coupled-cs

Если у вас есть viewmodels для ваших просмотров, является ли сервисный уровень подходящим местом для предоставления каждой модели просмотра? Например, в образце кода сервисного уровня существует метод

    public IEnumerable<Contact> ListContacts()
    {
        return _repository.ListContacts();
    }

Если вместо этого вам нужен IEnumerable, должен ли он идти на сервисном уровне или есть где-то еще, что это "правильное" место?

Возможно, более подходящим образом, если у вас есть отдельная модель просмотра для каждого представления, связанного с ContactController, должен ли ContactManagerService использовать отдельный метод для возврата каждой модели представления? Если сервисный уровень не является подходящим местом, где должны быть инициализированы объекты viewmodel для использования контроллером?

4b9b3361

Ответ 1

Как правило, нет.

Представленные модели предназначены для предоставления информации в представлениях и из них и должны быть конкретными для приложения, в отличие от общего домена. Контроллеры должны организовывать взаимодействие с репозиториями, службами (здесь я делаю некоторые предположения об определении сервиса) и т.д., А также обрабатывают создание и проверку моделей представления, а также содержат логику определения представлений для рендеринга.

Пропуская модели представления на "сервисный" уровень, вы размываете свои слои и теперь можете смешивать смешанные приложения и презентации с тем, что должно быть сосредоточено на выполнении обязанностей на уровне домена.

Ответ 2

Нет, я так не думаю. Услуги должны заботиться только о проблемной области, а не о представлении результатов. Возвращаемые значения должны быть выражены в терминах объектов домена, а не представлений.

Ответ 3

В соответствии с традиционным подходом или теорией, ViewModel должен быть частью уровня пользовательского интерфейса. По крайней мере, имя так говорит.

Но когда вы приступите к его реализации самостоятельно с помощью Entity Framework, MVC, Repository и т.д., тогда вы поймете что-то еще.

Кому-то приходится сопоставлять модели Entity/DB с ViewModels (в конце упоминается DTO). Должно ли это быть сделано в [A] на уровне пользовательского интерфейса (через контроллер) или в [B] на уровне службы?

Я иду с опцией B. Вариант A - нет, потому что простой факт состоит в том, что несколько моделей сущностей объединяются вместе для создания ViewModel. Мы не можем передавать ненужные данные на уровень пользовательского интерфейса, тогда как в варианте B служба может воспроизводить данные и передавать только требуемый/минимальный уровень пользовательского интерфейса после сопоставления (в ViewModel).

Опять же, давайте перейдем к опции A, поместите ViewModel в слой пользовательского интерфейса (и модель сущности на уровне службы).

Если необходимо, чтобы сервисный уровень отображался в ViewModel, тогда для уровня сервиса необходимо получить доступ к ViewModel в слое пользовательского интерфейса. Какая библиотека/проект? Viewmodel должен быть в отдельном проекте на уровне пользовательского интерфейса, и на этот проект должен ссылаться уровень обслуживания. Если ViewModel не находится в отдельном проекте, тогда есть круговая ссылка, поэтому не нужно идти. Удивительно, что уровень доступа к уровню доступа к пользовательскому интерфейсу был невелик, но мы все же могли справиться с ним.

Но что, если с помощью этой услуги есть другое приложение UI? Что делать, если есть мобильное приложение? Каким может быть ViewModel? Должна ли служба получать доступ к одному проекту модели просмотра? Будут ли все проекты пользовательского интерфейса обращаться к одному проекту ViewModel или у них есть свои собственные?

После этих соображений мой ответ заключался бы в том, чтобы поместить проект Viewmodel в Service Layer. Каждому слою пользовательского интерфейса в любом случае необходимо получить доступ к Сервису. И может быть много подобных ViewModels, которые все они могли бы использовать (следовательно, отображение становится проще для уровня сервиса). В настоящее время сопоставление осуществляется через linq, что является еще одним плюсом.

Наконец, это обсуждение DTO. А также о аннотации данных в ViewModels. ViewModels с аннотациями данных (Microsoft.Web.Mvc.DataAnnotations.dll) не могут находиться на уровне сервиса, а не находятся на уровне пользовательского интерфейса (но ComponentModel.DataAnnotations.dll может находиться на уровне сервиса). Таким образом, DTO фактически является ViewModel, потому что в основном будет одно на одно отображение между ними (скажем, с помощью AutoMapper). Опять же, DTO все еще имеет логику, необходимую для пользовательского интерфейса (или нескольких приложений) и находится на уровне обслуживания. И интерфейс ViewModel пользовательского интерфейса (если мы используем Microsoft.Web.Mvc.DataAnnotations.dll) - это просто копировать данные из DTO, добавив к нему некоторые "поведение" /атрибуты.

[Теперь эта дискуссия собирается сделать интересный поворот, прочитанный...: I]

И не думаю, что атрибуты аннотации данных предназначены только для интерфейса. Если вы ограничиваете проверку с помощью System.ComponentModel.DataAnnotations.dll то одна и та же модель просмотра также может использоваться для проверки интерфейса и бэкэнд (таким образом, удаление UI-res-viewmodel-copy-of-DTO). Более дополнительные атрибуты также могут использоваться в моделях сущностей. Например: с помощью .tt, для баз данных Entity Framework можно автогенерировать атрибуты проверки для выполнения некоторых проверок db, таких как max-length, перед отправкой на задний конец. Другим преимуществом является то, что, если проверка базы данных изменяется в БД, тогда .tt(читает спецификацию db и создает атрибут для класса сущности) автоматически подберет это. Это может привести к сбою тестов модуляции UI, что является большим плюсом (поэтому мы можем исправить его и проинформировать все пользовательские интерфейсы/потребители вместо случайного забывания и сбоя). Да, обсуждение продвигается к хорошему дизайну рамки. Как вы можете видеть, все это связано с тем, что уровень проверки, стратегия unit test, стратегия кэширования и т.д.

Хотя это не связано напрямую с вопросом. "ViewModel Façade", упомянутый в этом, должен смотреть канал 9 link, также стоит изучить. Он начинается ровно через 11 минут 49 секунд в видео. Поскольку это будет следующий шаг/мысль, как только ваш текущий вопрос, приведенный выше, будет разобран: "Как организовать режимы просмотра?"

Также в вашем примере "_repository.ListContacts()" возвращает viewmodel из репозитория. Это не зрелый путь. Репозитории должны предоставлять модели сущностей или модели db. Это преобразуется для просмотра моделей, и эта модель представления возвращается сервисным уровнем.

Ответ 4

Я полагаю, это зависит от того, что вы считаете "сервисами". Мне никогда не нравился термин сервис в контексте одного класса; это невероятно расплывчато и не говорит вам о фактической цели класса.

Если "сервисный уровень" - это физический уровень, такой как веб-служба, то абсолютно нет; службы в контексте SOA должны раскрывать домен/бизнес-операции, а не данные, а не логику представления. Но если услуга используется как абстрактная концепция для дальнейшего уровня инкапсуляции, я не вижу никаких проблем с ее использованием так, как вы описываете.

Просто не смешивайте понятия. Если ваш сервис имеет дело с моделями просмотров, он должен быть презентационным сервисом и обладать над верхней частью реальной модели, никогда напрямую не касаясь базы данных или какой-либо бизнес-логики.

Ответ 5

Это немного зависит от того, где я работаю - у нас обычно есть контроллер, который потребляет некоторые службы, а затем объединяет возвращаемый DTO в "ViewModel", который затем передается клиенту - либо через результат JSON или привязаны к шаблону Razor.

Вещь составляет около 80% времени - отображение DTO в ViewModel было 1-1. Мы начинаем двигаться в направлении "Где нужно, просто потребляйте DTO напрямую, но когда DTO и что нам нужно в нашем клиенте/представлении не совпадают, - тогда мы создаем ViewModel и делаем сопоставление между объектами по мере необходимости".

Хотя я все еще не убежден, что это лучшее или правильное решение, поскольку оно заканчивается тем, что приводит к некоторым горячим дискуссиям о том, добавим ли мы X в DTO, чтобы удовлетворить потребности этого взгляда?