Рекомендации по сопоставлению DTO с объектом домена?


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

Ситуация:

У нас есть много объектов домена. Мы используем модель CSLA, поэтому наши доменные объекты могут быть довольно сложными, и они содержат свой собственный доступ к данным. Вы не хотите, чтобы передать их вокруг на проводе. Мы мы собираемся написать несколько новых сервисов, которые будут возвращать данные в нескольких форматах (.Net, JSON и т. д.). По этой (и другим причинам) мы также создаем бережливый объект передачи данных для передачи по проводу.

мой вопрос заключается в том, как должен быть подключен объект DTO и домен?

моя первая реакция-использовать Fowler, DTO pattern-type solution. Я видел это много раз, и это кажется мне правильным. Объект домена не содержит ссылки на DTO. Внешняя сущность ("сопоставитель "или" ассемблер") вызывается для создания DTO из объекта домена. Обычно существует ORM на стороне объекта домена. Недостатком этого является то, что" картограф", как правило, становится чрезвычайно сложным для любой реальной ситуации и может быть очень хрупким.

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

есть ли другие способы? Является ли один из способов выше стоит использовать? Если да, то почему?

Спасибо за любую информацию заранее.

9 65

9 ответов:

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

лично я пытаюсь сохранить отображение из моих доменных сущностей и возложить ответственность на то, что я называю "уровнем менеджера / службы". Это уровень, который находится между приложением и ответчиком(ами) и обеспечивает бизнес-логику, такую как координация рабочего процесса (если вы изменяете A, вам может потребоваться также изменить B, чтобы служба A работала со Службой B).

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

вы можете использовать automapper, такие как тот, что написал Джимми Богард который не имеет связи между объектами и полагается на соблюдение соглашений об именах.

мы используем шаблоны T4 для создания классов отображения.

Pro-читаемый человеком код, доступный во время компиляции, быстрее, чем во время выполнения mapper. 100% контроль над кодом (можно использовать частичные методы/шаблон шаблона для расширения функциональности на специальной основе)

Con-исключение некоторых свойств, коллекций объектов домена и т. д., изучение синтаксиса Т4.

Как вы видите, чтобы реализовать конструктор внутри класса DTO, который принимает в качестве параметра объект домена?

сказать... Что-то вроде этого

class DTO {

     // attributes 

     public DTO (DomainObject domainObject) {
          this.prop = domainObject.getProp();
     }

     // methods
}

другое возможное решение: http://glue.codeplex.com.

характеристики:

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

вы также можете попробовать Otis, объект-объект mapper. Понятия подобны отображению NHibernate (атрибут или XML).

http://code.google.com/p/otis-lib/wiki/GettingStarted

Я могу предложить инструмент, который я создал и с открытым исходным кодом размещен в CodePlex: EntitiesToDTOs.

отображение от DTO к сущности и наоборот реализуется методами расширения, они составляют ассемблерную сторону каждого конца.

вы заканчиваете с кодом, как:

Foo entity = new Foo();
FooDTO dto = entity.ToDTO();
entity = dto.ToEntity();

List<Foo> entityList = new List<Foo>();
List<FooDTO> dtoList = entityList.ToDTOs();
entityList = dtoList.ToEntities();

почему бы нам не сделать так?

class UserDTO {
}

class AdminDTO {
}

class DomainObject {

 // attributes
 public DomainObject(DTO dto) {
      this.dto = dto;
 }     

 // methods
 public function isActive() {
      return (this.dto.getStatus() == 'ACTIVE')
 }

 public function isModeratorAdmin() {
      return (this.dto.getAdminRole() == 'moderator')
 }

}


userdto = new UserDTO();
userdto.setStatus('ACTIVE');

obj = new DomainObject(userdto)
if(obj.isActive()) {
   //print active
}

admindto = new AdminDTO();
admindto.setAdminRole('moderator');

obj = new DomainObject(admindto)
if(obj.isModeratorAdmin()) {
   //print some thing
}

@FrederikPrijck (или) кто-то: пожалуйста, предложите. В приведенном выше примере DomainObject зависит от DTO. Таким образом, я могу избежать кода, чтобы сделать отображение dto domainobject.

или класс DomainObject может расширять класс DTO?

другой вариант-использовать ModelProjector. Он поддерживает все возможные сценарии и очень прост в использовании с минимальными затратами.