entity framework - pattern - Opinión sobre la arquitectura basada en cebolla ASP.NET MVC
repository asp net mvc (4)
¿Cuál es su opinión sobre la siguiente arquitectura MVC ASP.NET inspirada en la cebolla ''genérica'':
Las capas, explicaron:
Núcleo : contiene el modelo de dominio. Por ejemplo, esos son los objetos de negocio y su relación. Estoy utilizando Entity Framework para diseñar visualmente las entidades y las relaciones entre ellas. Me permite generar un script para una base de datos. Obtengo modelos tipo POCO generados automáticamente, a los que puedo referirme libremente en la siguiente capa (Persistencia), ya que son simples (es decir, no son específicos de la base de datos).
Persistencia - Interfaz de repositorio e implementaciones. Básicamente las operaciones de CRUD en el modelo de dominio.
BusinessServices - Una capa de negocios alrededor del repositorio. Toda la lógica de negocios debe estar aquí (por ejemplo, GetLargestTeam()
, etc.). Utiliza operaciones CRUD para componer objetos devueltos u obtener / filtrar / almacenar datos. Debe contener todas las reglas de negocio y validaciones.
Web (o cualquier otra IU) : en este caso particular, es una aplicación MVC, pero la idea detrás de este proyecto es proporcionar UI, impulsada por lo que ofrecen los servicios empresariales. El proyecto UI consume la capa de negocios y no tiene acceso directo al repositorio. El proyecto MVC tiene sus propios modelos de Vista, que son específicos para cada situación de Vista. No estoy tratando de alimentarlo a la fuerza Modelos de Dominio.
Las referencias son así: IU -> Servicios empresariales -> Repositorio -> Objetos centrales
Lo que me gusta de esto:
- Puedo diseñar mis objetos, en lugar de codificarlos manualmente. Estoy obteniendo objetos modelo generados por código.
- La interfaz de usuario es impulsada / impuesta por la capa de negocios. Se pueden codificar diferentes aplicaciones de UI contra el mismo modelo de negocio.
Sentimientos encontrados sobre:
- Bien, tenemos una implementación de repositorio conectable, pero ¿con qué frecuencia tiene implementaciones diferentes de la misma interfaz de persistencia?
- Lo mismo ocurre con la interfaz de usuario: tenemos la capacidad técnica para implementar diferentes aplicaciones de interfaz de usuario con las mismas reglas de negocios, pero ¿por qué lo haríamos cuando podemos simplemente mostrar diferentes vistas (móviles, de escritorio, etc.)?
- No estoy seguro de si la interfaz de usuario solo debe comunicarse con la capa empresarial a través de los modelos de vista, o si debo usar modelos de dominio para transferir datos, como lo hago ahora. Para la visualización, estoy usando modelos de vista, pero para la transferencia de datos estoy usando modelos de Dominio. ¿Incorrecto?
Lo que no me gusta:
- Ahora se hace referencia al proyecto Core en todos los demás proyectos, porque quiero / tengo que acceder a los modelos de Dominio. En la arquitectura clásica de Onion, el núcleo es referenciado solo por la siguiente capa.
- DbContext se implementa en el proyecto .Core, porque está siendo generado por Entity Framework, en el mismo lugar donde se encuentra .edmx. Realmente quiero usar .EDMX para el diseño del modelo visual, pero siento que DbContext pertenece a la capa de persistencia, en algún lugar dentro de la implementación del repositorio específica de la base de datos.
Como pregunta final, ¿qué es una buena arquitectura que no está sobre diseñada (como una cebolla completa, donde tenemos inyecciones, localizadores de servicios, etc.) pero al mismo tiempo proporciona cierta flexibilidad razonable, en lugares donde lo haría? ¿Lo necesitas de manera realista?
Gracias
En mi opinión:
- "En la arquitectura clásica de Onion, el núcleo es referenciado solo por la siguiente capa". Eso no es cierto, el núcleo debe ser referencia por cualquier capa ... recuerde que la dirección de la dependencia entre las capas es hacia el centro (núcleo).
"las capas de arriba pueden usar cualquier capa debajo de ellas" Por Jeffrey Palermo http://jeffreypalermo.com/blog/the-onion-architecture-part-3/
- Acerca de su EF, está en el lugar equivocado ... debería estar en la capa de Infraestructura y no en la capa Núcleo. Y use POCO Generator para crear las entidades (clases POCO) en Core / Model. O use un Mapeador automático para que pueda asignar el Modelo básico (objetos de negocio) al Modelo de entidad (Entidades de EF)
Por otro lado, creé una aplicación simple que utiliza la arquitectura de cebolla para mostrar las dependencias entre las capas y cómo debería implementarse. http://www.jaider.net/posts/935-onion-architecture-in-action-get-started/
Lo que has hecho se ve bastante bien y es básicamente una de las dos arquitecturas estándar que veo mucho.
Sentimientos encontrados sobre:
Bien, tenemos una implementación de repositorio conectable, pero ¿con qué frecuencia tiene implementaciones diferentes de la misma interfaz de persistencia?
A menudo se puede decir que Pluggable es un buen diseño, pero nunca he visto a un equipo intercambiar una implementación importante de algo por algo más. Solo modifican lo existente. La "capacidad de conexión" de IMHO solo es útil para poder simular componentes para pruebas de unidades automatizadas.
No estoy seguro de si la interfaz de usuario solo debe comunicarse con la capa empresarial a través de los modelos de vista, o si debo usar modelos de dominio para transferir datos, como lo hago ahora. Para la visualización, estoy usando modelos de vista, pero para la transferencia de datos estoy usando modelos de Dominio. ¿Incorrecto?
Reconozco que los modelos de visualización son una UI (MVC Web), si agregó un tipo diferente de IU, por ejemplo, podría no requerir modelos de visualización o podría necesitar algo diferente. Así que creo que la capa de negocios debería devolver entidades de dominio y permitir que se asignen para ver los modelos en la capa de interfaz de usuario.
Lo que no me gusta:
Ahora se hace referencia al proyecto Core en todos los demás proyectos, porque quiero / tengo que acceder a los modelos de Dominio. En la arquitectura clásica de Onion, el núcleo es referenciado solo por la siguiente capa.
Como han dicho otros, esto es bastante normal. Normalmente todo termina teniendo una dependencia en el dominio.
DbContext se implementa en el proyecto .Core, porque está siendo generado por Entity Framework, en el mismo lugar donde se encuentra .edmx. Realmente quiero usar .EDMX para el diseño del modelo visual, pero siento que DbContext pertenece a la capa de persistencia, en algún lugar dentro de la implementación del repositorio específica de la base de datos.
Creo que esto es una consecuencia del Entity Framework. Si lo usó en el modo "Código Primero", realmente puede, y generalmente tiene, tener el contexto y el repositorio en la capa de Persistencia con el Dominio (representado como clases de POCO) en lo que ha llamado Núcleo.
Como pregunta final, ¿qué es una buena arquitectura que no está sobre diseñada (como una cebolla completa, donde tenemos inyecciones, localizadores de servicios, etc.) pero al mismo tiempo proporciona cierta flexibilidad razonable, en lugares donde lo haría? ¿Lo necesitas de manera realista?
Como mencioné anteriormente, no me preocuparía la necesidad de intercambiar cosas excepto para permitir pruebas unitarias automatizadas. A menos que exista un requisito específico que conozca, esto lo hará muy probable.
¡Buena suerte!
Wow, hay mucho que decir aquí! ;-)
En primer lugar, hablemos de la arquitectura en general.
Lo que puedo ver aquí es que no es realmente una arquitectura Onion. Olvidó la capa más externa, la capa "Resolución de dependencia". En una arquitectura Onion, depende de esta capa conectar las interfaces Core a las implementaciones de Infraestructura (donde debería residir su proyecto Persistence).
Aquí hay una breve descripción de lo que debería encontrar en una aplicación de Onion. Lo que sucede en la capa Core es todo exclusivo del negocio: modelo de dominio, flujos de trabajo de negocios ... Esta capa define todas las necesidades técnicas de implementación como interfaces (es decir, interfaces de repositorios, interfaces de registro, interfaces de sesión ...). La capa Core no puede hacer referencia a ninguna biblioteca externa y no tiene un código de tecnología específica. La segunda capa es la capa de infraestructura. Esta capa proporciona implementaciones para interfaces Core no empresariales. Aquí es donde puede llamar a su base de datos, a sus servicios web ... Puede hacer referencia a cualquier biblioteca externa que necesite para proporcionar implementaciones, implementar tantos paquetes de nugget como desee :-). La tercera capa es su interfaz de usuario, bueno, ya sabe qué poner allí ;-) Y la última capa, es la Resolución de dependencia de la que hablé anteriormente.
La dirección de la dependencia entre las capas es hacia el centro.
Así es como podría verse:
La pregunta ahora es: cómo encajar lo que ya has codificado en una arquitectura Onion.
Núcleo: contiene el modelo de dominio.
Sí, este es el lugar correcto!
Persistencia - Interfaz de repositorio e implementaciones
Bueno, necesitarás separar interfaces con implementaciones. Las interfaces deben moverse a Core y las implementaciones deben moverse a la carpeta Infraestructura (puede llamar a este proyecto Persistence).
BusinessServices - Una capa de negocios alrededor del repositorio. Toda la lógica de negocios debería estar aquí.
Esto debe moverse en Core, pero no debe usar implementaciones de repositorios aquí, ¡simplemente manipule interfaces!
Web (o cualquier otra interfaz de usuario): en este caso particular, es una aplicación MVC
guay :-)
Necesitará agregar un proyecto "Bootstrapper", solo eche un vistazo here para ver cómo proceder.
Acerca de tus sentimientos encontrados:
No discutiré la necesidad de tener repositorios o no, encontrará muchas respuestas en .
En mi proyecto ViewModel tengo una carpeta llamada "Builder". Depende de mis Constructores discutir con las interfaces de mis servicios empresariales para obtener datos. El constructor recibirá listas de objetos Core.Domain y los asignará al ViewModel correcto.
Sobre lo que no te gusta:
En la arquitectura clásica de Onion, el núcleo es referenciado solo por la siguiente capa.
Falso :-) Cada capa necesita que el Core tenga acceso a todas las interfaces definidas allí.
DbContext se implementa en el proyecto .Core, porque está siendo generado por Entity Framework, en el mismo lugar donde está .edmx.
Una vez más, no es un problema tan pronto como es realmente fácil editar la plantilla T4 asociada a su EDMX. Solo necesita cambiar la ruta de los archivos generados y puede tener el EDMX en la capa de Infraestructura y los POCO en su proyecto Core.Domain.
¡Espero que esto ayude!
Yo inyecto mis servicios en mis controladores. Los servicios devuelven DTO que residen en Core. El modelo que tiene se ve bien, no uso el patrón de repositorio, pero muchas personas lo hacen. Es difícil trabajar con EF en este tipo de arquitectura, por eso elegí Nhibernate.
Una posible respuesta a tu pregunta final.
- NÚCLEO
- DOMINIO
- DI
- INFRAESTRUCTURA
- PRESENTACIÓN
- SERVICIOS