Как я могу прикрепить файлы ресурсов уровня пользовательского интерфейса к аннотациям данных модели домена? - PullRequest
1 голос
/ 18 декабря 2011

Этот вопрос действительно имеет большие архитектурные последствия, и я приветствую любые предложения или предложения по этому вопросу:

Я больше из школы мысли Мартина Фаулера, когда дело доходит до ООП. Я считаю, что вы должны иметь возможность напрямую отображать доменные объекты в пользовательском интерфейсе. Если у меня есть объект Car, я смогу отобразить его на веб-странице. Модель предметной области - это сквозная проблема, а не слой. Рассмотрение доменной модели как слоя приводит к анемичной доменной модели. Я не верю в DTO в архитектуре ООП.

Модель представления для меня - это способ составления доменных сущностей, требуемых в вашем представлении. Это не DTO. Я не понимаю, в чем причина использования модели представления, такой как DTO, хотя это кажется обычной практикой - использовать автопереработчик?

Таким образом, используя подход метаданных, я поместил аннотации данных в мою модель предметной области, чтобы дать подсказкам реализации пользовательского интерфейса о том, как визуализировать и проверять сущности. Мне нравится иметь модель домена richER.

В MVC3 как это можно сделать (в частности, используя аннотацию отображения данных) с помощью файла ресурсов, который находится на уровне пользовательского интерфейса? Есть ли нативная реализация для этого или мне нужно самому заняться творчеством? Или я где-то ошибся в моем подходе?

Ответы [ 2 ]

1 голос
/ 18 декабря 2011

Я не согласен.

С одной стороны, некоторые из атрибутов, которые вы будете использовать для указания способа отображения свойства сущности на веб-странице, берутся из пространства имен System.Web, а не из пространства имен System.ComponentModel.DataAnnotations. Помещая эти атрибуты в свойства вашей доменной модели, ваша доменная модель зависит от System.Web. Например, есть атрибут [HiddenInput], который указывает MVC3 визуализировать поле как input type = "hidden". Это не в System.CompoenentModel.DataAnnotations.

Во-вторых, я не думаю, что вам нужны атрибуты аннотации данных в свойствах вашей сущности, чтобы иметь богатую модель домена. Богатая модель предметной области происходит от классов, которые обертывают знания в контекст. Клиентское приложение не должно знать что-либо о домене, чтобы использовать его. Вы получаете богатую модель предметной области с классами, методами и свойствами, которые описывают знания, используя вездесущий язык. Атрибуты DataAnnotations плохо подходят для вездесущего языка imo. И ваш домен - это больше, чем просто ваша сущность. Существуют фабрики, сервисы и другие шаблоны, которые вы можете использовать для построения богатой доменной модели. Домен только с сущностями и метаданными звучит для меня анемично.

В-третьих, у вас может быть сущность, которая должна отображаться на вашем веб-сайте различными способами. Когда кто-то ищет автомобиль, вы можете отобразить только марку, модель, год и миниатюру. Когда кто-то нажимает на результат поиска, вы можете отобразить несколько фотографий, обзоров и т. Д. Если бы вы использовали атрибут UIHint для объекта, чтобы сообщить веб-интерфейсу, как визуализировать автомобиль, вы не сможете получить разные стратегии рендеринга автомобиля в разных контекстах.

Наконец, да, automapper действительно отлично подходит для DTO-преобразования ваших сущностей в модели представления. По сути, он позволяет вам заполнять копии объекта, отсоединенного от домена, для конкретных задач пользовательского интерфейса. Здесь можно безопасно использовать атрибуты HiddenInput и UIHint, чтобы сообщить MVC3, как визуализировать данные.

Ответ на комментарий 1

Что касается UIHint, я упомянул об этом здесь, потому что он имеет особое значение для MVC3 EditorTemplates. В случаях, когда частичное представление предполагает получение входных данных, какова структура представления? Текстовые поля, раскрывающиеся списки и входные элементы, которые часто соответствуют объектам и их свойствам в некотором совокупном корне. Поэтому вам потребуется некоторое представление сущностей для инкапсуляции данных. Ваш DTO также может быть совокупным корнем с глубиной. Вы можете иметь корневой DTO со скалярными свойствами (текст / дата / bool), свойствами навигации (раскрывающийся список) и свойствами коллекции (ul / ol / table).

Мы создаем соответствующие модели представления для многих объектов в сводном корне и реализуем их как представления с использованием EditorTemplates. Если мы когда-нибудь захотим переключиться на другой EditorTemplate, мы можем применить UIHint к свойству viewmodel. Таким образом, мы можем сказать ему, чтобы "визуализировать местоположение как карту Google". Automapper может сопоставить навигационные свойства и свойства коллекции с соответствующими моделями представления, формируя настолько сложное представление сущностей вашего домена, сколько вам нужно для пользователя.

Простите, если я неправильно понимаю, что вы подразумеваете под плоским dto.

Ответ на комментарий 2

Viewmodel dto может сгладить / денормализовать некоторые свойства (используя automapper), если ваши требования требуют этого. Например, рассмотрим университетский объект. У него может быть много имен на многих языках (переводы), что намекает на сущность UniversityName в совокупности, а университет имеет коллекцию имен (1..n). Из этих имен 1 может представлять собой OfficialName / NativeName, а другое может представлять TranslatedName для CurrentUICulture пользователя. Другие сущности в коллекции могут представлять TranslatedNames, которые пользователь не понимает, и их не нужно беспокоить.

Если у вас есть представление, которое интересуется только этими 2 именами в коллекции, вы можете преобразовать их в первоклассные свойства в модели представления:

public class UniversityViewModel
{
    public string OfficialName { get; set; }
    public string TranslatedName { get; set; }
    // ...other properties
}

Это случай, когда денормализованная частьсущность при преобразовании в модель представления dto может иметь смысл.Обратите внимание, что модель представления является анемичной - пустой контейнер для передачи данных из контроллера в представление.Это прекрасно, и на самом деле, это поощряется.

Ответ на оригинальный вопрос

Чтобы ответить на исходный вопрос, полезно подумать о модели вашего домена и объектахв качестве слоя - более конкретно, нижний слой .Многоуровневое программное обеспечение легче понять, если вы считаете, что различные проблемы в приложении зависят от других проблем.MVC3 - это уровень представления / пользовательского интерфейса, который будет зависеть от уровней, расположенных под ним - один из тех, которые являются уровнем вашего домена.

Если вы хотите получить доступ к файлу ресурса в пользовательском интерфейсе из уровня домена, вы идете в противоположном направлении.Вы сделаете низкий уровень зависимым от более высокого уровня.Если библиотека вашего домена зависит от библиотеки UI для ресурса, а библиотека UI зависит от домена для сущностей, вы в итоге получаете циклическую зависимость.Я думаю, что вы могли бы сделать это, используя рефлексию, если вам нужно, но в этом случае вы будете бороться с рамками.MVC и .NET в целом могут быть не лучшим выбором для вас, если это так.

Я на самом деле считаю файлы ресурсов сквозной задачей.Наше приложение покрыто i18n, и часто мы обнаруживаем, что нам нужны одни и те же языковые текстовые ресурсы как в домене, так и в интерфейсе пользователя.

Нет ничего плохого в том, чтобы поместить атрибут Display в сущность.Но если вы хотите использовать ресурсы для него, то либо поместите этот ресурс на уровень домена, либо, если вы считаете, что он там не принадлежит, на более низкий уровень.Таким образом, к нему могут получить доступ как домен, так и пользовательский интерфейс.

0 голосов
/ 10 января 2012

Итак, я поместил файл ресурсов в модель домена и добавил собственный HiddenFieldAttribute, чтобы мне не приходилось ссылаться на сборку MVC в модели домена.

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

Спасибо olivehour за интересное обсуждение и предложение, что можно размещать файлы ресурсов в сборке модели домена.

...