Entity Framework y separación de capas

12

Estoy tratando de trabajar un poco con Entity Framework y recibí una pregunta sobre la separación de capas.

Usualmente uso el enfoque UI -> BLL -> DAL y me pregunto cómo usar EF aquí.

Mi DAL generalmente sería algo así como

GetPerson(id)
{
    // some sql
    return new Person(...)
}

BLL:

GetPerson(id)
{
    Return personDL.GetPerson(id)
}

Interfaz de usuario:

Person p = personBL.GetPerson(id)

Mi pregunta ahora es: dado que EF crea mi modelo y DAL, ¿es una buena idea envolver EF dentro de mi propio DAL o es solo una pérdida de tiempo?

Si no necesito envolver EF, ¿seguiría colocando mi Model.esmx dentro de su propia biblioteca de clases o estaría bien simplemente colocarlo dentro de mi BLL y trabajar allí?

Realmente no puedo ver la razón para envolver EF dentro de mi propio DAL, pero quiero saber qué están haciendo otras personas.

Entonces, en lugar de tener lo anterior, dejaría de lado el DAL y simplemente haría:

BLL:

GetPerson(id)
{
    using (TestEntities context = new TestEntities())
    {
            var result = from p in context.Persons.Where(p => p.Id = id)            
                    select p;
    }
}

¿Qué hacer?

Thomas
fuente

Respuestas:

13

El ejemplo que usted proporciona es una arquitectura en capas. Sé que se simplifica intencionalmente, pero:

Su capa de presentación está directamente vinculada a la entidad Persona. Esto está bien solo en los casos más simples, y definitivamente no cuando intentas definir tus capas.

El método GetPerson también está utilizando una práctica bastante mala de crear un nuevo contexto para cada llamada. Debería obtener el contexto en el constructor, y será proporcionado por su contenedor IOC.

Una estructura simple pero efectiva que he usado es:

  • Project.Core: contiene modelos de vista e interfaces.
  • Project.DAL: con mi EDMX y el código generado.
  • Project.BLL - lógica de negocios.
  • Project.Web: la aplicación web en sí.

Es importante observar que:

  • Core no depende de ninguna otra solución.
  • DAL no depende de ninguna otra solución.
  • Project.Web depende de Core, pero no de DAL ni BLL.
  • BLL depende de Core y DAL.
Boris Yankov
fuente
1
Core parecería ser una capa de objeto de negocio.
sq33G
Esto es más o menos lo que uso también, sin embargo, agregaría archivos DLL adicionales para atender las declaraciones de interfaz. De esta manera solo hace referencia a las interfaces (y usa algo como [url = unity.codeplex.com/font>Unity[/url] para DI) y puede estar seguro de que no hay dependencias extrañas que haya inducido accidentalmente.
Ed James
Normalmente, sin EF, creo mi propia clase Person en una capa "Modelo", por lo que tengo UI, BLL, DAL y Model donde: UI conoce BLL y Model. BLL conoce DAL y Model. DLL conoce el modelo. ¿También crea sus propios "modelos de vista" y por qué no usa los que genera EF? (Sé que esto va en contra de la arquitectura en capas, pero ¿cuántas veces cambias realmente la forma en que obtienes los datos?)
Thomas
@Thomas envolviendo los modelos de vista en algo abstracto hará que las pruebas unitarias sean mucho más fáciles.
sq33G
3
model! = ver modelo
Boris Yankov
2

No necesita envolver su EDMX en nada.

Si puede prever la posibilidad de tener que cambiar de EF a algún otro enfoque, es posible que desee ampliar sus objetos de negocio (aprovechando las clases parciales) para implementar interfaces definidas en una capa de Business Object separada.

Luego, desde su código, solo tratará con esas interfaces y no con las clases concretas generadas. Es posible que se necesite un pequeño código de pegamento para mantener esto unido; que con el EDMX puede ser tu DAL.

sq33G
fuente
Entonces, si no estoy promoviendo ningún cambio de EF a otro enfoque, ¿mi código anterior estaría bien? Entonces, ¿solo tendría UI y BLL (donde el EDMX está en BLL)?
Thomas
Mi respuesta pragmática sería sí. Con la advertencia de que es posible que desee colocar el EDMX en su propio ensamblaje pequeño si será grande y mayormente estático, por lo que no necesitará recompilarlo / redistribuirlo con tanta frecuencia.
sq33G
Ah, buen punto sobre la recompilación / redistribución :)
Thomas
2

Hay dos enfoques generales para las capas: capas estrictas y capas relajadas.

Un enfoque estrictamente estratificado restringe los componentes en una capa para interactuar solo con sus pares y con la capa directamente debajo.

Una aplicación relajada en capas afloja las restricciones de manera que un componente pueda interactuar con los componentes de cualquier capa inferior.

El uso de capas relajadas puede mejorar la eficiencia porque el sistema no tiene que reenviar llamadas simples de una capa a la siguiente. Por otro lado, el uso de capas relajadas no proporciona el mismo nivel de aislamiento entre las capas y hace que sea más difícil cambiar una capa inferior sin afectar las capas superiores.

Para soluciones grandes que involucran muchos componentes de software, es común tener una gran cantidad de componentes en el mismo nivel de abstracción que no son cohesivos. En este caso, cada capa puede descomponerse adicionalmente en uno o más subsistemas cohesivos. La figura 2 ilustra una posible notación de lenguaje de modelado unificado (UML) para representar capas que están compuestas de múltiples subsistemas.

conclusión: si no necesita la capa intermedia, piérdala; no todas las aplicaciones requieren el mismo enfoque y, de alguna manera, agregar una capa solo con el propósito de crear capas tendrá penalidades en el costo de la complejidad y el mantenimiento.

omarqa
fuente