ASP.NET Core - Repository e Unit Of Work - II
Hoje vou apresentar novamente o padrão Repository e Unit Of Work usando a abordagem feita no Domain Driven Design. |
Continuando a primeira parte do artigo vamos criar os controladores LivrosController e CatalogosController na pasta Controllers do projeto Livraria.API.
Controlador : LivrosController
Vamos criar o controlador LivrosController na pasta Controllers:
'1- LivrosController
using Livraria.Domain.Entities; using Livraria.Domain.Interfaces; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Threading.Tasks;
namespace Livraria.API.Controllers [HttpGet] [HttpGet("genero")] [HttpGet("{id}")] [HttpPost] await _unitOfWork.LivrosRepo.Add(livro); return new CreatedAtRouteResult("Get", new { id = livro.Id }, livro); // PUT api/<Books>/5 if (result == null) if (result.Id != livro.Id) _unitOfWork.LivrosRepo.Update(livro); return Ok(); [HttpDelete("{id}")] if (livro == null) _unitOfWork.LivrosRepo.Delete(livro); |
A seguir vamos criar o controlador CatalogosController na mesma pasta:
2- CatalogosController
using Livraria.Domain.Entities; using Livraria.Domain.Interfaces; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Threading.Tasks;
namespace Livraria.API.Controllers [HttpGet] [HttpGet("{id}")] if (catalogo == null) return catalogo; [HttpPut("{id}")] var result = await _unitOfWork.LivrosRepo.Get(id); if (result == null) if (result.Id != catalogo.CatalogoId) _unitOfWork.CatalogosRepo.Update(catalogo); return Ok(); [HttpPost] return CreatedAtAction("GetCatalogo", new { id = catalogo.CatalogoId }, catalogo); [HttpDelete("{id}")] _unitOfWork.CatalogosRepo.Delete(catalogo); return OK(); |
Em ambos os controladores injetamos a instância da Unit Of Work e trabalhamos com o respectivo repositório acessando a implementação genérica.
Na figura abaixo temos uma representação simplificada da atuação do padrão Unit Of Work:
Vemos que o Unit Of Work atua como uma camada entre o controlador e o repositório genérico, e vai funcionar como um armazenamento centralizado para receber a instância do DbContext. Com isso garantimos que para unidade de transação que se estende por vários repositórios seja concluída para todas as entidades ou que falhe totalmente, já que todas elas vão compartilhar a mesma instância do contexto representando pelo DbContext.
Assim quando incluirmos dados para as entidades Catalogo e Livro, em uma única transação, ambas vão usar a mesma instância do DbContext. Sem isso cada repositório iria gerar e manter sua própria instância de DbContext, e, isso pode levar a problemas no futuro uma vez que cada DbContext terá sua própria lista na memória de alterações dos registros, das entidades, que estão sendo adicionadas/ atualizadas/ modificadas, em uma única transação. Nesse caso, se o SaveChanges de um dos repositórios falhar e o outro for bem-sucedido, isso resultará em inconsistência do banco de dados. Para evitar isso usamos o padrão Unit of Work.
Executando o projeto teremos o seguinte resultado:
Pegue o projeto aqui: Livraria.zip
"Guia-me na tua
verdade, e ensina-me, pois tu és o Deus da minha salvação; por ti estou
esperando todo o dia."
Salmos 25:5
Referências:
C# - Obtendo a data e a hora por TimeZone
C# - O Struct Guid - Macoratti.net
C# - Checando Null de uma forma mais elegante e concisa
DateTime - Macoratti.net
Null o que é isso ? - Macoratti.net
Formatação de data e hora para uma cultura ...
C# - Calculando a diferença entre duas datas
NET - Padrão de Projeto - Null Object Pattern - Macoratti
C# - Fundamentos : Definindo DateTime como Null ...
C# - Os tipos Nullable (Tipos Anuláveis) - Macoratti.net