asp.net-mvc repository-pattern service-layer

ASP.NET MVC con capa de servicio y capa de repositorio, ¿dónde deberían definirse las interfaces?



asp.net-mvc repository-pattern (1)

Introducción

Esto es algo que también me he preguntado. Una pregunta candente que siempre tengo es similar a la tuya;

¿Cuál sería una buena convención de nomenclatura?

¿Cómo debo nombrar las cosas? ¿Deben ir en carpetas o proyectos?

Después de buscar alrededor, sospecho que la respuesta es que realmente no importa . Lo importante es que su solución tiene una arquitectura sensible y que intenta seguir buenas prácticas, como SOLID .

Mis héroes de ASP.NET MVC sobre este tema son Jeffrey Palermo , Steve Smith y Jimmy Bogard .

Arquitectura de cebolla

Jeffrey Palermo discute una combinación de ideas antiguas, pero las reúne y le da el nombre visualmente estimulante de Onion Architecture (una lectura recomendada). Jeffrey muestra un buen enfoque del problema de dónde colocar las cosas. Explica que en el centro (o en la parte superior) de tu aplicación tienes tu Core . Esta capa es donde debe colocar interfaces como IRepository e IService .

Casi todas las interfaces deben ir en el núcleo y todo lo demás (otros proyectos) puede hacer referencia al núcleo. De esta manera, todo conoce la estructura esquelética de la aplicación sin conocer los detalles de la implementación.

Intente tener la referencia de la capa de UI lo menos posible (dentro de lo razonable). En una de mis aplicaciones, mi capa UI (MVC) solo hace referencia al Núcleo. Todo lo que necesita se inyecta en ella con inyección de dependencia .

Steve Smith analiza Onion Architecture e ideas similares con demostraciones en las mejores prácticas de la solución MVC: una solución al problema de la solución

Mi solución

En mis soluciones MVC tengo una estructura típica como esta:

  • MyProject.Core
  • MyProject.Domain
  • MyProject.DependencyInjection
  • MyProject.Infrastructure
  • MyProject.Web
  • MyProject.Tests

El Core contiene mis interfaces. Generalmente se divide en carpetas como Servicios, Modelos, Dominio, Repositorios, etc.

La capa de dominio solo hace referencia al núcleo y contiene mi implementación. Proporciona muchas de las clases concretas para la abstracción del dominio en el núcleo. Se ocupa de una gran cantidad de lógica de negocios, procesamiento, manejo de comandos, clases de gerentes, implementaciones de servicios concretos, etc. Considero que es una capa bastante interna, por lo que hace referencia lo menos posible.

La capa DependencyInjection contiene mi paquete / marco DI elegido y los detalles de implementación. Lo considero una capa exterior; es similar a la interfaz de usuario o la infraestructura, por lo que está bien si hace referencia a muchos. No es necesario que esta capa sea un proyecto separado y muchas personas le dirán que no haga esto. Está bien; Haz lo que funcione para la complejidad de tu proyecto. Me gusta que mi DI sea su propia cosa. Lo bueno de estar tan separado es que podría reemplazar el marco DI por otro diferente y las cosas estarían bien. Ninguna capa hace referencia al proyecto DI.

La capa de infraestructura contiene información sobre el registro, el envío de correos electrónicos y el acceso a los datos. Contendrá mi ORM de elección. No son cosas de lógica de negocios y no son cosas de UI. Es el ferrocarril de mi solución para hacer las cosas. Está en la capa exterior pero solo hace referencia al Núcleo.

La capa web es mi proyecto MVC y solo hace referencia al Core.

Complejidad y pensamientos finales.

He encontrado respuestas a preguntas similares aquí, pero tienden a involucrar una arquitectura más complicada de lo que he descrito aquí.

Es un buen punto. Es importante tener en cuenta la complejidad de su problema. Pero no se desanime con buenas prácticas de solución. Mi solución y Onion Architecture no son necesariamente muy complejas y en realidad no abultan su solución. Sólo mantienen las cosas separadas.

En la Estructura del Proyecto Evolutivo , Jimmy Bogard habla de que las cosas son demasiado complejas. Si lo que he dicho parece demasiado complejo, siga los consejos de Jimmy y póngalo todo en el proyecto (su capa de UI). Eso está bien, siempre y cuando se adapte a ti.

Recuerda tomar mi solución solo como una idea, algo para considerar; Mi enfoque es un intento de seguir los mejores consejos, pero estoy seguro de que solo he tenido mucho éxito; Puedo (y debo) seguir mejorando.

Estoy en el proceso de determinar una arquitectura en capas bastante simple para una aplicación .NET MVC que tiene una capa de repositorio y una capa de servicio. He encontrado algunos ejemplos bastante claros y simples, en particular www.asp.net , y algunas preguntas y respuestas aquí, pero estoy buscando algo que sea un poco más simple, adecuado para pequeñas aplicaciones, pero que use diferentes proyectos, para obtener el idea a través de El ejemplo que vinculé anteriormente tiene el repositorio y el servicio como clases en el espacio de nombres de los Modelos. Eso no es suficiente para una clara separación para que pueda ilustrarlo correctamente.

Tengo un proyecto separado para el repositorio que implementa la interfaz IRepository. Existe un proyecto independiente para el Servicio que implementa IService y toma un depósito de IR (inyección de constructor). El Servicio implementa IService. Es suficiente para este ejemplo que el controlador ejemplifique el servicio, no es necesario un contenedor IoC todavía. Piense en ello como un paso intermedio para comprender las mejores prácticas arquitectónicas, parte de una secuencia que se construye progresivamente para incluir la inyección de dependencia y posiblemente más capas.

La pregunta es, ¿dónde debería definir IRepository y IService? Tanto los proyectos de servicio como los de repositorio deben hacer referencia a ellos, por supuesto. Parece claro entonces que deberían definirse en otro proyecto al que se hace referencia tanto en el servicio como en los proyectos de repositorio. Si es así, ¿cuál sería una buena convención de nomenclatura? ¿Algo así como los contratos XXXX?

Del mismo modo, para los modelos de datos que se pasan entre las capas de presentación, servicio y repositorio, ¿es aceptable tener un proyecto separado denominado XXXXModels referenciado por todas las capas? Entiendo que, en algunos casos, los modelos que se pasan entre la capa de servicio y el repositorio pueden diferir de los que se pasan entre la capa de servicio y la capa de presentación, pero el principio es el mismo.

He encontrado respuestas a preguntas similares aquí, pero tienden a involucrar una arquitectura más complicada de lo que he descrito aquí. Estoy buscando lograr una ilustración realmente simple y clara de las dos capas que se pueden ver como uno o dos pasos arriba, haciendo referencia a la capa de datos y teniendo lógica empresarial en los controladores, eso es todo. Sé que hay un argumento sólido y válido para ir directamente a la mejor práctica, pero no todos están preparados para dar ese salto de una vez.