usar tres sistemas que porque por diagrama desarrollo datos capas capa arquitectura c# design-patterns architecture

c# - tres - que es arquitectura 3 capas



Capa de lógica de negocios y capa de acceso a datos: dependencia circular (8)

Estoy teniendo un pequeño problema de Arquitectura. En mi proyecto, tengo una capa de lógica de negocios (BLL) que contiene todas mis reglas comerciales, modelos y API OO para la interfaz. Cada objeto tiene métodos estáticos como getById que devuelven una instancia de dicho objeto. Cada objeto también tiene métodos como guardar y eliminar. Este es un código OO muy sencillo.

Ahora tengo una capa de DataAccess (DAL), contenida en un espacio de nombres separado, para cada objeto BLL tengo una DataClass o "Repository" que ejecuta los comandos getById y save. Entonces, de alguna manera, los métodos save y getById de BLL son una capa delgada alrededor de los métodos de DataClass.

public static NewsItem GetByID(int id) { return DataFactory.GetNewsItemRepository().GetNewsItemById(id); }

Para que DataClasses devuelva objetos BLL, necesitan conocer el BLL. entonces ahora tenemos:

GUI ---> BLL <----> DAL

The DataFactory solo devuelve objetos que implementan una interfaz, por lo que puedo ocultar detalles de implementación como "OracleNewsItemRepository".

Pero ahora, por lo que me ha estado molestando desde que comencé la programación orientada a objetos. En mi solución actual, tanto BLL como DAL necesitan conocerse entre sí. Esta es una Dependencia Circular, y es una buena práctica evitar dependencias circulares. También solo quiero exponer las interfaces (y mi DataFactory) y no mis clases. Esto se puede hacer colocando la capa DAL en un ensamble separado. Lo cual tendría sentido. Sin embargo, Visual Studio no permite que dos Ensambles se refieran entre sí. Otra pregunta sobre esto: modificadores de acceso interno C #

De alguna manera, creo que tengo mi patrón de acceso a datos completo mal. Parece que estoy convulsionando el patrón ActiveRecord con otras cosas como DataMappers. He pasado mucho tiempo en el sitio de Martin Fowler, pero esos patrones se describen muy genéricos y se ilustran con un diagrama UML muy abstracto.

Ellos no resuelven mi problema. Tal vez soy un poco anal, y no existe el "patrón perfecto de acceso a datos". Y lo que hago ahora no parece terriblemente mal. Pero cómo hago las cosas ahora, parece fuera de lugar ...

¿Algunas ideas?


Ahora es un poco viejo, pero quizás deberías haber considerado poner los pocos / interfaces en otro ensamblaje.

Project.Data references Project.Entities Project.BL references Project.Entities and Project.Data Project.UI references Project.Entities and Project.BL

Aquí no hay referencias circulares.


Creo que su patrón de acceso a datos está bien. Lo que no está haciendo es acoplar su BLL con OracleDAL. Estás uniendo las interfaces DAL. Es absolutamente necesario un poco de acoplamiento o nunca se puede hacer nada.

Supongo que las clases DataFactory y INewsItemRepository existen fuera de su capa DAL. El siguiente es un ejemplo de cómo están organizadas mis soluciones. No uso ActiveRecord, por lo que puede que esto no te convenga a la perfección.

Core (Project) Domain Business Entities Data Repository Interfaces **Your DataFactory** OracleData (Project) Data Oracle Repository Implementations SqlData (Project) Data Sql Repository Implementations UI (Project)

Espero que esto ayude.


DAL debe ser abstracto, por lo que debe contener solo objetos ADO.NET simples que interactúen con la base de datos back-end, por ejemplo, conexión DataAdapter, DataReader, etc. Con eso a mano puede hacer referencia a DAL en su capa de Biz, y cuando se trata de sus entidades con un poco de abstracción puede resolver todos sus problemas, por ejemplo, si tiene clase de cliente, puede crear una clase de cliente abstaractoin que implemente el las operaciones básicas para interactuar con DAL, como guardar, actualizar y recuperar datos, y en otra clase que hereda la clase de abstracción, anulan la implementación de métodos de clase base para cumplir con su validación de Biz, etc.


En mi opinión:

La capa de acceso a datos (DAL) debe operar en POCO (objetos CLR antiguos) utilizando operaciones tales como: SaveNewsItem ( NewsItemDAO newsItemDAO ) . Los POCO son sus DAO (Objetos de acceso a datos).

La capa empresarial debe contener la lógica para convertir un objeto de acceso a datos (DAO) en un objeto comercial enriquecido, que probablemente sea solo el DAO más algunas operaciones, así como cualquier decoración / enriquecimiento.

El DAL no debería tener conocimiento alguno sobre la capa lógica de negocios. En teoría, debería poder ser llamado desde cualquier cliente. Por ejemplo, ¿qué pasaría si quisiera separar el DAL de la aplicación y desplegarlo como un servicio independiente que se expone a través de WCF?

Como se mencionó, las operaciones DAL, por ejemplo, SaveNewsItem, deben ser accedidas por el BO a través de interfaces, quizás a través de la inyección de dependencia / IoC.


IceHeat, el ejemplo de @Craig Wilson tiene más sentido y probablemente se deriva de este artículo: http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx .

Esto es MUY digno de ser leído y aborda el desarrollo impulsado por el dominio que resuelve los problemas que usted enfrenta aquí. Lo recomendaría a cualquiera, incluso si no le das a un mono sobre NHibernate es un gran artículo.


Puede usar interfaces / inyección de dependencia para resolver su problema.

La capa de negocio (BL) contiene las interfaces de acceso a datos (DA) que el (posiblemente más de un) DAL necesita implementar. Los proyectos DAL tienen referencias de proyecto a BL para que puedan escupir objetos comerciales (BO) e implementar las interfaces DA.

Sus BO pueden llamar a DataFactory, que puede crear instancias de un objeto DA mediante inyección o reflexión de dependencia.

He utilizado este patrón en muchas de nuestras aplicaciones aquí en el trabajo (tanto basado en la web y el cliente inteligente), y funciona muy bien.


Quitaría cualquier método Get () y Save () de su BLL (modelo de dominio) ... esto es lo que haría

La GUI solicitará a Repository que obtenga el objeto de dominio por id ... y una vez que la GUI tenga el objeto de dominio, podrá navegar hasta otros objetos. De esta forma, la capa de dominio no necesita saber nada sobre los repositorios.

Dentro del repositorio puede devolver el objeto de dominio que cargue de forma lenta o cargue por completo el objeto gráfico del objeto ... esto dependerá de lo que necesite ...

Aquí hay una buena reseña sobre el mismo tema ... La reconstitución de objetos

Lea el comentario de Deyan Petrov sobre cómo usar el proxy dinámico


Solo para ser claros, me gusta pensar en un Modelo de Negocio y Lógica de Negocios como dos capas separadas. Su modelo de negocio son sus POCO (objetos simples de CLR antiguos). Su capa de lógica de negocios sería responsable de realizar validaciones, transacciones, etc. utilizando tanto su modelo de negocio como una interfaz para su DAL que podría conectarse de varias maneras (Spring, Castle o su propio contenedor IoC).

Una buena forma de lograr cero dependencias en su DAL con su modelo de negocio es utilizar un marco de mapeo de relaciones de objeto (ORM) ya construido como NHibernate (un enchufe desvergonzado para mi marco ORM favorito).