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

StackOverflow https://stackoverflow.com/questions/3002168

Вопрос

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

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

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

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

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

Это было полезно?

Решение

Вообще, нет.

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

Утечка просмотра моделей в слою «Сервис», вы размываете свои слои, и теперь имейте возможное приложение и презентационные специфические, смешанные с тем, что следует сосредоточиться на обязанности доменных обязанностей.

Другие советы

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

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

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

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

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

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

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

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

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

Наконец, есть эта дискуссия о DTO.А также о аннотации данных в ViewModels.ViewModels с аннотациями данных (Microsoft.Web.Mvc.DataAnnotations.dll) не могут находиться на уровне сервиса, вместо этого они находятся на уровне пользовательского интерфейса (но ComponentModel.DataAnnotations.dll может находиться на уровне сервиса).Если все проекты находятся в одном решении (.sln), то не имеет значения, на какой слой вы его разместите.В корпоративных приложениях каждый уровень будет иметь свое собственное решение.

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

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

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

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

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

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

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

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

Это стало немного «это зависит», где я работаю - мы, как правило, имели контроллер, потребляющий некоторые услуги (ы) - то сочетать возвращенные Dто в «ViewModel», который затем передан клиенту - через результат JSON или связан в шаблоне бритвы.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top