Pregunta

He visto un montón de preguntas relacionadas con el mapeo dtos a objetos de dominio, pero no sentí que respondió a mi pregunta. He utilizado muchos métodos antes y tener mis propias opiniones, pero estoy buscando algo un poco más concreto.

La situación:

Tenemos muchos objetos de dominio. Estamos utilizando un modelo CSLA para que nuestros objetos de dominio pueden ser bastante complejos y que contienen su propio acceso a datos. Usted no desea pasar estos alrededor del cable. Vamos a estar escribiendo algunos nuevos servicios que devolverán los datos en varios formatos (.Net, JSON, etc.). Por esta (y otras razones) también estamos creando una, la transferencia de datos de objeto magra para pasar alrededor en el cable.

Mi pregunta es: ¿Cómo se deben conectar el DTO y el objeto de dominio

Mi primera reacción es utilizar un Fowler, DTO-tipo de patrón solución . He visto este hecho muchas veces y se siente bien para mí. El objeto de dominio no contiene ninguna referencia a la DTO. Una entidad externa (un "asignador" o "ensamblador") es llamado para crear un DTO de un objeto de dominio. Normalmente hay un ORM en el lado del objeto de dominio. La desventaja de esto es que el "asignador" tiende a ser extremadamente complejo para cualquier situación real y puede ser muy frágil.

Otra idea es poner adelante para el objeto de dominio "contener" el DTO, ya que es sólo un objeto de datos magra. Las propiedades serían objeto de dominio interno referencia a las propiedades de DTO y podrían simplemente devolver el DTO si se le pide. Puedo ver ningún problema con esto, pero se siente mal. He visto algunos artículos en los que las personas que utilizan NHibernate parecían utilizar este método.

¿Hay otras maneras? Es una de las formas anteriores vale la pena usar? Si es así, o si no, ¿por qué?

¿Fue útil?

Solución

Una de las ventajas de tener un mapeador que se encuentra entre su dominio y su DTO no es tan appearent cuando sólo se está apoyando una sola asignación, pero a medida que el número de asignaciones de los aumentos, que tiene ese código aislado del dominio ayuda a mantener el dominio sencillo y más ligera. No se le saturan su dominio con una gran cantidad de peso extra.

En lo personal, yo trato de mantener el mapeo de mis entidades del dominio y poner la responsabilidad en lo que llamo "capa Gerente / servicio". Esta es una capa que se encuentra entre la aplicación y el repositorio (s), y proporciona la lógica de negocio, tales como la coordinación del flujo de trabajo (Si modifica A, es posible que tenga que modificar también B así que el servicio funcionará con un servicio B).

Si tuviera una gran cantidad de posibles formatos de acabar, yo podría mirar a la creación de un formateador enchufable que podría utilizar el patrón del visitante, por ejemplo para transformar mis entidades, pero no he encontrado todavía una necesidad para cualquier cosa este complejo.

Otros consejos

Se podría utilizar un AutoMapper como el escrito por Jimmy Bogard que no tiene ninguna conexión entre los objetos y se basa en las convenciones de nomenclatura que se adhiere a.

Utilizamos plantillas T4 para crear las clases de mapeo.

Pro - código legible humano disponible en tiempo de compilación, más rápido que un asignador de tiempo de ejecución. 100% de control sobre el código (puede utilizar patrón métodos / plantilla parcial para extender la funcionalidad sobre una base ad-hoc)

Contras -. Exclusión de ciertas propiedades, colecciones de objetos de dominio, etc., el aprendizaje de la sintaxis T4

Otra posible solución:. http://glue.codeplex.com

Características:

  • mapeo bidireccional
  • mapeo automático
  • Mapping entre diferentes tipos
  • anidado de mapeo y aplanamiento
  • Las listas y matrices
  • Verificación de las relaciones
  • Prueba de la asignación
  • Properties, campos y métodos

¿Cómo ve usted para implementar un constructor dentro de la clase DTO que toma como parámetro un objeto de dominio?

Say ... Algo como esto

class DTO {

     // attributes 

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

     // methods
}

También puede tratar de Otis, un asignador de objeto a objeto. Conceptos son similares a NHibernate mapeo (atributo o XML).

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

puedo sugerir una herramienta que creé y que es de código abierto alojado en CodePlex:. EntitiesToDTOs

Asignación de DTO a la Entidad y viceversa es implementado por métodos de extensión, estos componen el lado Ensamblador de cada extremo.

Se termina con un código como:

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();

¿Por qué no podemos hacerlo así?

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 (o) a alguien: Por favor sugerir. En el ejemplo anterior DomainObject es depende del DTO. Por este modo puede evitar que el código para hacer el mapeo de la dto <->. DomainObject

o DomainObject clase puede extiende la clase DTO?

Otra opción sería utilizar ModelProjector . Es compatible con todos los escenarios posibles y es muy fácil de usar con huella mínima.

Podemos usar fábrica, Memento, y Builder para eso. Fábrica de ocultar los detalles sobre cómo crear instancia de modelo de dominio de DTO. Memento se hará cargo de la serialización / deserialización del modelo de dominio a / desde DTO y puede incluso tener acceso a los miembros privados. La voluntad Builder permite la cartografía de DTO al dominio con interfaz fluida.

Mantener la lógica de mapeo interior de su entidad significa que su objeto de dominio es ahora consciente de un "detalle de implementación" que no tiene por qué conocer. Generalmente, un DTO es su puerta de entrada al mundo exterior (ya sea de una solicitud entrante o por medio de una lectura de un servicio / base de datos externa). Desde la entidad es parte de la lógica de negocio, es probable que sea mejor para mantener esos detalles fuera de la entidad.

Mantener el mapeo en otro lugar sería la única alternativa - pero ¿dónde debe ir? He intentado introducir mapeo de objetos / servicios, pero, después de todo lo dicho y hecho, parecía manipulación excesiva (y probablemente era). He tenido cierto éxito utilizando AutoMapper y como para proyectos más pequeños pero herramientas como AutoMapper vienen con sus propias dificultades. He tenido algunos bastante difícil encontrar temas relacionados con las asignaciones debido a las asignaciones de AutoMapper están implícitos y completamente desacoplado del resto de su código (no como "separación de las preocupaciones", sino más bien como un "¿de dónde viene el mapeo de mala muerte en directo") para que a veces puede ser difícil de localizar. No quiere decir que AutoMapper no tiene sus usos, porque lo hace. Sólo pienso mapeo debe ser algo que es tan obvio y transparente como sea posible para evitar problemas.

En lugar de crear una capa de servicio de mapas, he tenido mucho éxito manteniendo mis asignaciones dentro de mis dtos. Desde dtos todos los días se sientan en el límite de la aplicación, se pueden hacer consciente del objeto comercial y encontrar la manera de mapa de / a ellos. Aun cuando el número de asignaciones de escala a una cantidad razonable funciona limpiamente. Todas las asignaciones están en un lugar y que no tienen que manejar un montón de servicios de mapas en el interior de su capa de datos, Anticorrupción Layer o capa de presentación. En cambio, el mapeo es sólo un detalle de implementación delegado en el DTO involucrado con la petición / respuesta. Desde serializadores generalmente sólo serializar propiedades y campos cuando se va a enviar a través del cable, no se debe ejecutar en cualquier problema. En lo personal, he encontrado esta la opción más limpia y puedo decir, en mi experiencia, que funciona bien en una gran base de código.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top