EF Core - Criando aplicações mais Robustas
Hoje vamos abordar alguns procedimentos que nos ajudam a criar aplicações mais robustas usando o Entity Framework Core. |
Quem não deseja criar aplicações mais robustas ?
O termo 'robustas' aqui refere-se a ter uma aplicação com baixo acoplamento e alta coesão.
Acoplamento
- Acoplamento é o nível de dependência/conhecimento que pode existir
entre as classes; Coesão
- Coesão é o nível de integralidade
interna de uma classe; (Veja o principio da responsabilidade única -
SRP) Portanto quanto mais forte o acoplamento e mais baixa a coesão de uma classe mais difícil ela será de entender, manter e ser reusada. |
Assim, vou apresentar algumas abordagens (baseadas nas considerações de Jon P Smith) que nos ajudam a criar aplicações que usam o EF Core de forma mais robusta. Essas abordagens são baseadas em princípios e padrões de software que eu com frequência trato no site e serão apresentadas de forma resumida.
1- Separação de responsabilidades - Usando a arquitetura correta
Esse princípio de software conhecido como Separation of Concerns (SoC) dita a primeira abordagem e reza que :
Devemos agrupar o código com funcionalidades semelhantes ou fortemente relacionadas, separando-os em um lugar comun. Em termos de projeto na plataforma .NET isso implica colocar o código em um projeto diferente. Com isso estamos obtendo uma alta coesão.
Devemos tornar cada projeto o mais independente possível, onde cada parte do código deve ter uma interface clara e um escopo de trabalho que dificilmente deve ser alterado devido a outras alterações em partes do projeto. Com isso estamos obtendo um baixo acoplamento.
Em nosso projeto nunca devemos chamar os comandos do EF Core diretamente da aplicação, pois isso fere o princípio da separação das responsabilidades.
Na figura a seguir temos um exemplo de arquitetura que fere o princípio Soc e que apresenta uma baixa coesão e alto acoplamento:
Na figura a seguir temos uma abordagem que respeita o princípio SoC e apresenta alta coesão e baixo acoplamento:
Aqui podemos usar diferentes arquiteturas como: Domain Drive Design, Layered
Architecture, N-Tier, SOA, etc. Para detalhes veja este link:
MSDN - rchitectural Patterns and Styles
2- A camada de serviço - Separando ações de dados de ações de apresentação
A camada de serviço ou Service layer é definida da seguinte forma por Martin Fowler :
"Define os limites de um aplicativo com uma camada de serviços que estabelece um conjunto de operações disponíveis e coordena a resposta do aplicativo em cada operação".
Tudo isso parece ótimo, mas como isso ajuda meus aplicativos ?
Usando a camada de serviço como um adaptador
Em uma arquitetura em camadas, geralmente existe uma incompatibilidade de dados
entre o banco de dados/ lógica de negócios e a camada de apresentação. A
abordagem DDD(Domain-Driven Design), diz que o
banco de dados e a lógica de negócios devem se concentrar nas regras de
negócios, enquanto a camada de apresentação visa proporcionar ao usuário uma
ótima experiência.
Por esse motivo, a Camada de serviço se torna uma
camada crucial, pois pode ser a camada que compreende os dois lados e pode
transformar os dados entre os dois mundos. Isso mantém a lógica de negócios e o
banco de dados organizados pelas necessidades da apresentação.
Da mesma forma,
ao fazer com que a Camada de Serviço forneça dados
pré-formatados exatamente da forma que a camada de apresentação precisa, torna
muito mais simples a camada de apresentação mostrar esses dados.
Ao lidar com acesso ao banco de dados via EF, a Camada de
Serviço usa o padrão Adapter para
transformar a partir da camada de acesso aos dados/lógica de negócios para
a camada de apresentação. Os bancos de dados tendem a minimizar a duplicação de
dados e maximizar os links relacionais entre os dados, enquanto a camada de
apresentação é usada para mostrar os dados de uma forma que o usuário achar
útil.
Assim utilizar uma camada de serviço que permite fazer essa comunicação é muito importante.
3- Escolhendo o padrão de acesso a dados correto
Existem várias maneiras diferentes de criar o acesso ao seu banco de dados via EF Core, com diferentes níveis de ocultação de código de acesso EF Core do restante da sua aplicação. Os mais usados são:
Aqui não existe uma regra que permita indicar qual é o melhor padrão a ser usado. Podemos descartar o último, que deve ser usado apenas em protótipos.
Para projetos muito complexos o primeiro padrão (Repo+UoW) pode se tornar muito dispendioso em termos de código e manutenção.
Assim o ideal é procurar sempre isolar o código EF Core usado.
4- Transformando o seu código de acesso a dados em serviço
Utilizar a injeção de dependência para injetar o código de acesso a dados na sua aplicação ASP .NET Core pode lhe trazer muitos benefícios.
Em primeiro
lugar, a injeção de dependência vai vincular dinamicamente o acesso ao seu
banco de dados nas partes do código da apresentação que precisam dele. Em
segundo lugar, com a utilização de interfaces, é muito fácil substituir as
chamadas para o código de acesso ao banco de dados por simulações para teste de
unidade.
A seguir temos as etapas principais para realizar essa tarefa em aplicações ASP
.NET Core:
1- Transforme o seu código de acesso ao banco de dados em repositórios. Você faz isso criando uma classe que contém métodos, que o código front-end precisa chamar.
2- Adicione uma interface para cada classe de repositório EF definindo a interface e a implementação;
3- Registre sua classe de repositório EF em sua interface no provedor de DI nativo da ASP .NET Core;
4- Injete a dependência no método do front-end se necessário. Na ASP.NET Core, você pode injetar um método Action usando o [FromServices];
Como resultado final teremos o código do banco de dados separado em sua classe própria e agora seu código de apresentação precisa apenas chamar o método sem saber o que ele contém. Além disso os testes de unidades ficam fáceis de implementar pois você pode verificar o código de acesso a dados substituindo o código na sua chamada do front-end por uma classe que simula os dados.
5- Crie uma camada de negócios (Domain Drive Design)
Os aplicativos
do mundo real são criados para fornecer algum tipo de serviço, desde a
manutenção de uma lista simples de itens no seu computador até o gerenciamento
de um reator nuclear. Todo problema do mundo real tem um conjunto de regras,
geralmente chamadas de regras de negócios ou pelo nome mais genérico, regras de
domínio.
A abordagem DDD (Domain-Driven Design) diz que o
problema de negócios que você está tentando resolver deve impulsionar todo o
desenvolvimento. Eric Evans trata disso em seu livro
Domain Drive Design, e continua explicando como a lógica de negócios
deve ser isolada de todo o resto, exceto as classes de banco de dados, para que
você possa dar toda a sua atenção ao que Eric Evans chama de "tarefa difícil"
de escrever a lógica de negócios.
Há muitos debates sobre se o EF Core é adequado para uma abordagem DDD, porque o
código da lógica de negócios é normalmente separado das classes de entidade EF
que ele mapeia para o banco de dados. A recomendação é aplicar os
conceitos do DDD usando o framework até quando ele não for hostil à aplicação
destes conceitos.
Como o assunto é muito extenso listo a seguir algumas diretrizes que devem nortear a aplicação do DDD com EF Core:
Concluindo
A abordagem recomendada para o desenvolvimento de software é fazê-lo funcionar e depois se preocupar em torná-lo mais rápido.
Outra abordagem mais sutil, atribuída a Kent Beck, é Make it Work é : Faça certo. Faça rápido.
De qualquer forma, esse princípio diz que devemos deixar o ajuste de desempenho para o fim. Assim:
Respondendo a essas perguntas você poderá traçar ações para otimizar o seu código e ajustar o desempenho do seu projeto.
"Portanto,
agora nenhuma condenação há para os que estão em Cristo Jesus, que não andam
segundo a carne, mas segundo o Espírito."
Romanos 8:1
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
ASP .NET Core 2 - MiniCurso Básico - Macoratti
ASP .NET Core - Macoratti
Conceitos - .NET Framework versus .NET Core - Macoratti
ASP .NET Core - Conceitos Básicos - Macoratti.net
EF Core - Iniciando com o Entity Framework Core - Macoratti
Apresentando o EF Core Power Tools - Macoratti.net
Curso Entity Framework Core 2.0 - Vídeo Aulas - Macoratti
EF Core - Usando o EF Core com Windows Forms - (Crud ... - Macoratti
EF Core 2.0 - Scaffolding DbContext e Models usando CLI - Macoratti