asp.net-mvc domain-driven-design viewmodel dto separation-of-concerns

asp.net mvc - ¿Dónde convertir un DTO a ViewModel?



asp.net-mvc domain-driven-design (4)

Primero, siempre use ViewModels explícitos para sus Vistas, no pase los DTOs hasta la Vista. Es un trabajo un poco más adelantado, pero le da más control sobre exactamente qué datos se necesitan en la Vista (también impide que un marco como EF cargue muchos datos adicionales que puede o no usar)

En segundo lugar, este artículo describe el patrón del orquestador http://www.simple-talk.com/dotnet/asp.net/never-mind-the-controller,-here-is-the-orchestrator/ que probablemente sea solo otro nombre más para Algún otro patrón, pero me gusta el formato.

Esencialmente, creas un orquestador para cada controlador. El orquestador toma los datos (por lo general, un ViewModel y cualquier otro tipo de datos básicos necesarios, particularmente los de HttpContext), y devuelve un ViewModel (si es necesario para la Vista, de lo contrario, algún otro tipo de retorno).

Este formato le brinda la ventaja de poder probar fácilmente la lógica real sin tener que intentar burlarse de las cosas de HttpContext que los Controladores necesitan.

He heredado un proyecto MVC2 usando un patrón DDD bastante estándar y decentemente bien mantenido. También he estado leyendo mucho sobre todo el debate DTO / ViewModel.

Actualmente nuestros DTO se utilizan a menudo como ViewModels . Honestamente, no hace una diferencia en lo que estamos haciendo, pero me gustaría usar ViewModels adecuados a medida que actualizamos el sitio.

Aquí está mi pregunta:

Los modelos de nuestro proyecto de "dominio" actualmente tienen las entidades y devuelven los DTO a mis controladores. Ahora necesito asignar ese DTO a un ViewModel. ¿Dónde debo hacer esto?

  • Justo en el controlador?
  • ¿En el proyecto de dominio?
  • ¿En otra parte?

Mantengo mis ViewModels junto con las vistas en nuestro proyecto "Web", por lo que me parece incorrecto convertir DTO -> ViewModel en el proyecto de dominio. También se siente mal hacerlo en el controlador.

¿Qué han hecho otros?

Editar:

Esta pregunta / respuesta sugiere manejarlo en el controlador. Seguro que es más fácil pensar en esto.


Suena como algo que quiere hacer en una clase / módulo de mapeo especialmente diseñado.

Personalmente, le daría a mi controlador una dependencia de un servicio de mapeo y luego delegaría la conversión real a eso antes de devolver la vista con el modelo de vista recién mapeado.

public class DemoController : Controller { private readonly IMappingService _mappingService; public DemoController(IMappingService mappingService) { _mappingService = mappingService; } public ActionResult Stuff() { var vm = _mappingService.Map(yourDto); return View(vm); } }


Un buen enfoque es sobrecargar el constructor en su ViewModel con un segundo constructor que tiene el dto como parámetro. Esto significa que puede manejar la asignación en el propio Modelo de vista. Esto mantiene su controlador agradable y ordenado sin tener que configurar un servicio de mapeo.


Los DTO son típicamente específicos de la tecnología. Por ejemplo, en el mundo .NET, es probable que sus DTO estén decorados con los atributos de serialización DataContract y DataMember . Además, los DTO junto con el servicio que los devuelve forman un adaptador para el dominio en términos de una arquitectura hexagonal . Adaptan su dominio a una tecnología de transporte específica como HTTP y, como tal, viven fuera de su dominio. En otras palabras, el dominio no debe tener conocimiento de los DTO, los DTO deben definirse en un proyecto separado. El proyecto que contiene el servicio debe tener un código de asignación que asigne objetos de dominio a DTO.

Un proyecto ASP.NET MVC es de naturaleza similar: adapta su servicio / DTO (u objetos de dominio directamente) a una tecnología de presentación, en particular a HTML. Como tal, los DTO no deben ser conscientes de ViewModels. En su lugar, el controlador MVC debe invocar la asignación entre DTO y ViewModels. Esto se puede hacer de varias maneras, pero lo que he encontrado que funciona mejor es un constructor en ViewModel que acepta un DTO. Además, en los casos en que una acción del controlador garantiza la creación de un DTO que se enviará al servicio, ViewModel puede contener un método para crear el DTO basado en ViewModel. Este contiene todo el código de mapeo en el ViewModel más cercano a los datos reales, una instancia del patrón experto en información . Otra forma de implementar esto sería usar algo como AutoMapper que utiliza el mapeo basado en convenciones para evitar el código repetitivo. Cualquier cosa más allá de eso lo consideraría una exageración a menos que sea requerido.

En muchos casos, su ViewModel termina pareciéndose al DTO pero con atributos específicos de ASP.NET MVC para el enlace y la validación. Aunque esto pueda parecer una violación de DRY , estas son responsabilidades realmente separadas.