14

En mi aplicación ASP.NET MVC, estoy usando la unidad de trabajo y los patrones de repositorio para el acceso a los datos.¿Dónde convertir el modelo de negocio para ver el modelo?

Usando la unidad de clase de trabajo y el repositorio definido dentro de ella, estoy buscando el conjunto relacionado de entidades en mi controlador. Con mi conocimiento para principiantes, puedo pensar en dos formas de obtener el modelo de negocio y convertirlo para ver el modelo.

  • Repositorio devuelve el modelo de negocio al controlador, este modelo de mapeado para ver modelo, o
  • propio repositorio convierte modelo de negocio para ver modelo y luego se devuelve al controlador.

Actualmente estoy usando la primera aproximación, pero el código de mi controlador comenzó a verse feo y largo para ver modelos con muchas propiedades.

Por otro lado, estoy pensando, ya que mi repositorio se llama UserRepository (por ejemplo), debería devolver el modelo de negocio directamente, en lugar de algún modelo que sea útil solo para vista única.

¿Cuál de estos le parece una mejor práctica para proyectos grandes? ¿Hay alguna manera alternativa?

Gracias.

+1

Mi [respuesta] [1] a esta pregunta debería explicar cómo se puede hacer esto mejor. [1]: http://stackoverflow.com/questions/3747383/best-practices-to-partition-model-code-to-logical-parts-in-mvc-which-is-the- bes/3747474 # 3747474 –

Respuesta

20

Repositories deben devolver modelos de dominio, no ver los modelos. En lo que respecta al mapeo entre los modelos y los modelos de vista, personalmente utilizo AutoMapper, así que tengo una capa de mapeo separada, pero esta capa se llama desde el controlador.

Así es como una acción típica controlador GET podría ser:

public ActionResult Foo(int id) 
{ 
    // the controller queries the repository to retrieve a domain model 
    Bar domainModel = Repository.Get(id); 

    // The controller converts the domain model to a view model 
    // In this example I use AutoMapper, so the controller actually delegates 
    // this mapping to AutoMapper but if you don't have a separate mapping layer 
    // you could do the mapping here as well. 
    BarViewModel viewModel = Mapper.Map<Bar, BarViewModel>(domainModel); 

    // The controller passes a view model to the view 
    return View(viewModel); 
} 

que por supuesto podría acortarse con un filtro de acción personalizada para evitar la lógica de asignación repetitivo:

[AutoMap(typeof(Bar), typeof(BarViewModel))] 
public ActionResult Foo(int id) 
{ 
    Bar domainModel = Repository.Get(id); 
    return View(domainModel); 
} 

El AutoMapa personalizada El filtro de acción se suscribe al evento OnActionExecuted, intercepta el modelo pasado al resultado de la vista, invoca la capa de asignación (AutoMapper en mi caso) para convertirlo a un modelo de vista y lo sustituye por la vista. Por supuesto, la vista está fuertemente tipada al modelo de vista.

+0

ty muchísimo. No sabía de Automapper. Es lo que necesito en mi problema. –

+0

¿Se puede probar el método de filtro de acción personalizado? ¿Cómo funcionaría el auto mapeador si se llama desde una prueba unitaria? –

+1

@JoshuaBarker, el objetivo de una prueba unitaria es que esté probando una funcionalidad de forma aislada. Entonces, ¿qué quieres probar de forma aislada aquí? El atributo AutoMap? Genial, adelante y escribe una prueba unitaria para eso. ¿O la acción de su controlador que está pasando el modelo de dominio a la vista? Genial, adelante y escribe una prueba unitaria para eso. ¿O el hecho de que la acción de su controlador está decorada con el atributo AutoMap? Genial, adelante y escribe una prueba unitaria para eso. Hasta el momento, ha escrito 3 pruebas de unidad con todo lo que necesita para verificar que la acción de su controlador funcionará como se espera. –

2

Creo que su repositorio debería devolver el modelo de negocio.

Luego puede utilizar una herramienta como Automapper para asignar automáticamente las propiedades a su modelo de vista y puede deshacerse del código de mapeo manual. Este enfoque es muy útil si no desea exponer todas las propiedades de la entidad comercial o su estructura de comples a la vista.

También puede encontrar este post útil, donde puede deshacerse de las llamadas de mapeo manual (más o menos) y también proporciona un buen ejemplo de cómo usar viewmodels, etc. (en mi opinión) - o al menos algún tipo de inspiración.

Extracto del poste (el atributo que hace el modelo forma busioness conversión al modelo de vista):

[AutoMap(typeof(Product), typeof(ShowProduct))] 
public ActionResult Details(int id) 
{ 
    var product = _productRepository.GetById(id); 

    return View(product); 
} 
+0

ty mucho. La respuesta de Darin es un poco detallada, así que estoy aceptando su respuesta. Espero que no te importe. –

+0

Gracias, eso es bueno. Gracias por la información: estoy de acuerdo en que la respuesta de Darin tiene el mismo contenido pero la presenta mejor (y, por lo tanto, es la mejor respuesta). Todavía te sugiero que leas el enlace, porque puede haber otras informaciones interesantes sobre Viewmodels, etc. –

+0

gracias. Lo estoy leyendo en este momento :) –

Cuestiones relacionadas