Estrutura de entidades e separação de camadas

12

Estou tentando trabalhar um pouco com o Entity Framework e tenho uma pergunta sobre a separação de camadas.

Eu costumo usar a interface do usuário -> BLL -> DAL abordagem e estou querendo saber como usar EF aqui.

Meu DAL normalmente seria algo como

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

BLL:

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

UI:

Person p = personBL.GetPerson(id)

Minha pergunta agora é: como a EF cria meu modelo e o DAL, é uma boa ideia incluir o EF no meu próprio DAL ou é apenas uma perda de tempo?

Se eu não precisar envolver o EF, ainda colocaria meu Model.esmx dentro de sua própria biblioteca de classes ou seria bom colocá-lo dentro do meu BLL e trabalhar alguns lá?

Não vejo realmente o motivo de incluir a EF no meu próprio DAL, mas quero saber o que as outras pessoas estão fazendo.

Então, em vez de ter o acima, eu deixaria de fora o DAL e faria:

BLL:

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

O que fazer?

Thomas
fonte

Respostas:

13

O exemplo que você fornece é quase uma arquitetura em camadas. Eu sei que é intencionalmente simplificado, mas:

Sua camada de apresentação está diretamente vinculada à entidade Pessoa. Isso é bom apenas nos casos mais simples e, definitivamente, não quando você está tentando definir suas camadas.

O método GetPerson também está usando uma prática bastante ruim de criar um novo contexto para cada chamada. Você deve obter o contexto no construtor e ele será fornecido pelo seu contêiner IOC.

Uma estrutura simples e eficaz que usei é:

  • Project.Core - contém modelos e interfaces de exibição.
  • Project.DAL - com meu EDMX e código gerado.
  • Project.BLL - lógica de negócios.
  • Project.Web - o aplicativo da web em si.

É importante observar que:

  • O núcleo não depende de nenhuma outra solução.
  • O DAL não depende de nenhuma outra solução.
  • O Project.Web depende do Core, mas não do DAL nem do BLL.
  • O BLL depende do Core e do DAL.
Boris Yankov
fonte
1
O núcleo parece ser uma camada de objeto de negócios.
sq33G
Isso é basicamente o que eu uso também, no entanto, eu adicionaria DLLs extras para atender às declarações da interface. Dessa forma, você apenas faz referência às interfaces (e usa algo como [url = unity.codeplex.com/ussyUnity[/url] para DI) e pode ter certeza de que não há dependências estranhas que você acidentalmente induziu.
Ed James
Normalmente, sem EF, eu crio minha própria classe Person em uma camada "Model", então eu tenho UI, BLL, DAL e Model, onde: A UI conhece BLL e Model. A BLL conhece a DAL e o Model. DLL conhece Model. Você também cria seus próprios "modelos de visualização" e por que não usa apenas os que a EF gera? (eu sei que isso vai contra a arquitetura em camadas, mas quantas vezes você realmente mudar a forma como você obter os dados?)
Thomas
@ A colocação de modelos de visualização em algo abstrato tornará muito mais fácil o teste de unidade.
sq33G
3
model! = view model
Boris Yankov
2

Você não precisa envolver seu EDMX em nada.

Se você puder prever a possibilidade de precisar mudar do EF para outra abordagem, convém estender seus objetos de negócios (aproveitando as classes parciais) para implementar interfaces definidas em uma camada de Objetos de Negócios separada.

Então, a partir do seu código, você lidará apenas com essas interfaces e não com as classes geradas concretas. Pode ser necessário um pequeno código de cola para manter isso unido; que com o EDMX pode ser seu DAL.

sq33G
fonte
Então, se eu não estiver prevendo alterações da EF para outra abordagem, meu código acima ficaria bem? Eu teria apenas interface do usuário e BLL (onde o EDMX está no BLL)?
Thomas
Minha resposta pragmática seria sim. Com a ressalva de que você pode realmente querer colocar o EDMX em sua própria pequena montagem, se for grande e principalmente estático, para que você não precise recompilar / redistribuí-lo com a mesma frequência.
sq33G
Ah, bom ponto sobre a recompilação / redistribuir :)
Thomas
2

Existem duas abordagens gerais para as camadas: estrita e descontraída.

Uma abordagem estritamente em camadas restringe os componentes em uma camada a interagir apenas com os pares e com a camada diretamente abaixo.

Um aplicativo em camadas relaxado afrouxa as restrições, de modo que um componente possa interagir com os componentes de qualquer camada inferior.

O uso de camadas relaxadas pode melhorar a eficiência, porque o sistema não precisa encaminhar chamadas simples de uma camada para a seguinte. Por outro lado, o uso de camadas relaxadas não fornece o mesmo nível de isolamento entre as camadas e dificulta a troca de uma camada inferior sem afetar as camadas superiores.

Para grandes soluções que envolvem muitos componentes de software, é comum ter um grande número de componentes no mesmo nível de abstração que não são coesos. Nesse caso, cada camada pode ser ainda decomposta em um ou mais subsistemas coesos. A Figura 2 ilustra uma possível notação UML (Unified Modeling Language) para representar camadas compostas de vários subsistemas.

conclusão: se você não precisar da camada intermediária, perca-a; nem todas as aplicações requerem a mesma abordagem e, de alguma forma, adicionar uma camada apenas para fins de camadas terá penalidades no custo e na manutenção da complexidade.

omarqa
fonte