Implementando o padrão de repositório no aplicativo ASP.NET MVC
O Padrão de Repositório é um dos padrões mais populares para criar um aplicativo de nível empresarial. Ele nos restringe a trabalhar diretamente com os dados no aplicativo e cria novas camadas para operações de banco de dados, lógica de negócios e interface do usuário do aplicativo.
O Padrão de Repositório é um dos padrões mais populares para criar um aplicativo de nível empresarial. Ele nos restringe a trabalhar diretamente com os dados no aplicativo e cria novas camadas para operações de banco de dados, lógica de negócios e interface do usuário do aplicativo. Se um aplicativo não seguir o Padrão de Repositório, ele poderá ter os seguintes problemas:
- Códigos de operações de banco de dados duplicados
- Necessidade de interface do usuário para operações de banco de dados de teste de unidade e lógica de negócios
- Necessidade de dependências externas para testar a lógica de negócios de teste de unidade
- Difícil de implementar o cache do banco de dados, etc.
O uso do Padrão de Repositório tem muitas vantagens:
- Sua lógica de negócios pode ser testada por unidade sem lógica de acesso a dados;
- O código de acesso ao banco de dados pode ser reutilizado;
- Seu código de acesso ao banco de dados é gerenciado centralmente, de modo que é fácil implementar qualquer política de acesso ao banco de dados, como cache;
- É fácil implementar a lógica de domínio;
- Suas entidades de domínio ou entidades de negócios são fortemente tipadas com anotações; e muito mais.
Na internet, existem milhões de artigos escritos em torno do Padrão de Repositório, mas neste, vamos nos concentrar em como implementá-lo em um ASP.NET MVC Aplicativo. Então vamos começar!
Antes de prosseguir e aprender sobre o Padrão de Repositório no ASP.NET MVC, recomendo que você verifique Infragistics biblioteca baseada em jQuery Ignite UI, que ajuda você a escrever e executar aplicativos da Web mais rapidamente. Você pode usar a biblioteca Ignite UI for JavaScript para ajudar a resolver rapidamente requisitos complexos de LOB em HTML5, jQuery, Angular, React ou ASP.NET MVC. (Você pode baixar uma avaliação gratuita do Ignite UI aqui).
Estrutura do Projeto
Vamos começar criando a estrutura do projeto para o aplicativo. Vamos criar quatro projetos:
- Projeto Principal
- Projeto de Infraestrutura
- Projeto de teste
- MVC Project
Cada projeto tem seu próprio propósito. Você provavelmente pode adivinhar pelos nomes dos projetos o que eles conterão: os projetos principais e de infraestrutura são bibliotecas de classes, o projeto Web é um projeto MVC e o projeto de teste é um projeto de teste de unidade. Eventualmente, os projetos no gerenciador de soluções terão a aparência mostrada na imagem abaixo:

À medida que avançamos neste post, aprenderemos em detalhes sobre o objetivo de cada projeto, no entanto, para começar, podemos resumir o objetivo principal de cada projeto da seguinte forma:
Até agora, nossa compreensão para diferentes projetos é clara. Agora vamos em frente e implementemos cada projeto um por um. Durante as implementações, exploraremos detalhadamente as responsabilidades de cada projeto.
Projeto Principal
No projeto principal, mantemos as entidades e as interfaces do repositório ou as interfaces de operação do banco de dados. O projeto principal contém informações sobre as entidades de domínio e as operações de banco de dados necessárias nas entidades de domínio. Em um cenário ideal, o projeto principal não deve ter nenhuma dependência de bibliotecas externas. Ele não deve ter nenhuma lógica de negócios, códigos de operação de banco de dados, etc.
Em suma, o projeto principal deve conter:
- Entidades de domínio
- Interfaces de repositório ou interfaces de operações de banco de dados em entidades de domínio
- Anotações de dados específicos do domínio
O projeto principal NÃO pode conter:
- Quaisquer bibliotecas externas para operações de banco de dados
- Business logic
- Código de operações do banco de dados
Ao criar as entidades de domínio, também precisamos tomar uma decisão sobre as restrições nas propriedades das entidades de domínio, por exemplo:
- Se uma determinada propriedade é necessária ou não. Por exemplo, para uma entidade Product, o nome do produto deve ser propriedade obrigatória.
- Se um valor de uma determinada propriedade está em determinado intervalo ou não. Por exemplo, para uma entidade Product, a propriedade price deve estar em determinado intervalo.
- Se o comprimento máximo de uma propriedade específica não deve receber valor. Por exemplo, para uma entidade Product, o valor da propriedade name deve ser menor que o comprimento máximo.
Pode haver muitas dessas anotações de dados nas propriedades das entidades de domínio. Há duas maneiras de pensar sobre essas anotações de dados:
- Como parte das entidades de domínio
- Como parte da lógica de operações do banco de dados
Depende puramente de nós como vemos as anotações de dados. Se os considerarmos parte da operação do banco de dados, podemos aplicar restrições usando a API das bibliotecas de operação do banco de dados. Vamos usar o Entity Framework para operações de banco de dados no projeto de infraestrutura, para que possamos usar a API fluente do Entity Framework para anotar dados.
Se os considerarmos parte do domínio, poderemos usar a biblioteca System.ComponentModel.DataAnnotations para anotar os dados. Para usar isso, clique com o botão direito do mouse na pasta Referência do projeto principal e clique em Adicionar referência. Na guia Estrutura, selecione System.ComponentModel.DataAnnotations e adicione ao projeto.
Estamos criando um ProductApp, então vamos começar criando a entidade Product. Para adicionar uma classe de entidade, clique com o botão direito do mouse no projeto principal e adicione uma classe e, em seguida, nomeie a classe Product.
using System.ComponentModel.DataAnnotations;
namespace ProductApp.Core
{
public class Product
{
public int Id { get; set; }
[Required]
[MaxLength(100)]
public string Name { get; set; }
[Required]
public double Price { get; set; }
public bool inStock { get; set; }
}
}
Anotamos as propriedades da entidade Product com Required e MaxLength. Ambas as anotações fazem parte de System.ComponentModel.DataAnnotations. Aqui, consideramos a restrição como parte do domínio, portanto, usamos anotações de dados no próprio projeto principal.
Criamos a classe Product Entity e também aplicamos anotação de dados a ela. Agora vamos em frente e criar a interface do repositório. Mas antes de criarmos isso, vamos entender, o que é uma Interface de Repositório?
A interface do repositório define todas as operações de banco de dados possíveis nas entidades de domínio. Todas as operações de banco de dados que podem ser executadas nas entidades de domínio fazem parte das informações do domínio, portanto, colocaremos a interface do repositório no projeto principal. A forma como essas operações podem ser executadas fará parte do projeto de infraestrutura.
Para criar uma interface de repositório, clique com o botão direito do mouse no projeto principal e adicione uma pasta chamada Interfaces. Depois que a pasta Interfaces for criada, clique com o botão direito do mouse na pasta Interface e selecione adicionar um novo item e, na guia Código, selecione Interface. Nomeie a interface IProductRepository
using System.Collections.Generic;
namespace ProductApp.Core.Interfaces
{
public interface IProductRepository
{
void Add(Product p);
void Edit(Product p);
void Remove(int Id);
IEnumerable GetProducts(); Product FindById(int Id);
}
}
Agora criamos uma classe de entidade Product e uma Product Repository Interface. Neste ponto, o projeto principal deve ficar assim:

Vamos em frente e construir o projeto principal para verificar se tudo está no lugar e seguir em frente para criar o projeto de infraestrutura.
Projeto de Infraestrutura
O principal objetivo do projeto de infraestrutura é realizar operações de banco de dados. Além das operações de banco de dados, ele também pode consumir serviços da Web, realizar operações de E/S etc. Assim, principalmente, o projeto de infraestrutura pode realizar as seguintes operações:
- Database operations
- Trabalhando com WCF e Web Services
- IO operations
Podemos usar qualquer tecnologia de banco de dados para realizar operações de banco de dados. Neste post, vamos usar o Entity Framework. Então, vamos criar um banco de dados usando a abordagem Code First. Na abordagem Code First, o banco de dados é criado com base nas classes. Aqui, o banco de dados será criado com base nas entidades de domínio do Projeto Principal.
Para criar o banco de dados a partir da entidade de domínio do projeto principal, precisamos executar estas tarefas:
- Create DataContext class
- Configurar a cadeia de conexão
- Criar a classe DataBase Initializer para propagar dados no banco de dados
- Implementar a interface IProductRepsitory
Adicionando referências
Primeiro, vamos adicionar referências ao projeto Entity Framework e ProductApp.Core. Para adicionar o Entity Framework, clique com o botão direito do mouse no projeto de infraestrutura e clique em Gerenciar Pacote Nuget. Na janela do Gerenciador de Pacotes, pesquise Entity Framework e instale a versão estável mais recente.
Para adicionar uma referência do projeto ProductApp.Core, clique com o botão direito do mouse no projeto de infraestrutura e clique em Adicionar referência. Na Janela de Referência, clique na guia Projeto e selecione ProductApp.Core.
DataContext class
O objetivo da classe DataContext é criar o DataBase na abordagem do Entity Framework Code First. Passamos uma cadeia de conexão no construtor da classe DataContext. Ao ler a cadeia de conexão, o Entity Framework cria o banco de dados. Se uma cadeia de conexão não for especificada, o Entity Framework criará o banco de dados em um servidor de banco de dados local.
In the DataContext class:
- Crie uma propriedade de tipo DbSet. Isso é responsável por criar a tabela para a entidade Product
- No construtor da classe DataContext, passe a cadeia de conexão para especificar informações para criar um banco de dados, por exemplo, nome do servidor, nome do banco de dados, informações de logon etc. Precisamos passar o nome da cadeia de conexão. nome onde o banco de dados seria criado
- Se a cadeia de conexão não for passada, o Entity Framework criará com o nome da classe de contexto de dados no servidor de banco de dados local.
- A classe productdatacontext herda a classe DbContext
A classe ProductDataContext pode ser criada conforme mostrado na listagem abaixo:
using ProductApp.Core;
using System.Data.Entity;
namespace ProductApp.Infrastructure
{
public class ProductContext : DbContext
{
public ProductContext() : base("name=ProductAppConnectionString") {}
public DbSet Products { get; set; }
}
}
Em seguida, precisamos trabalhar na cadeia de conexão. Conforme discutido anteriormente, podemos passar a cadeia de conexão para especificar informações de criação de banco de dados ou responder no Entity Framework para criar o banco de dados padrão no local padrão para nós. Vamos especificar a cadeia de conexão, por isso passamos um nome de cadeia de conexão ProductAppConnectionString no construtor da classe ProductDataContext. No arquivo App.Config, a cadeia de conexão ProductAppConnectionString pode ser criada, conforme mostrado na listagem abaixo:
<add name="ProductAppConnectionString" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ProductAppJan;Integrated Security=True;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
Classe Inicializador de Banco de Dados
Criamos uma classe inicializadora de banco de dados para propagar o banco de dados com algum valor inicial no momento da criação. Para criar a classe inicializador de banco de dados, crie uma classe que herda de DropCreateDatabaseIfModelChnages. Há outras opções de classes disponíveis para herdar a fim de criar uma classe inicializadora de banco de dados. Se herdarmos a classe DropCreateDatabaseIfModelChnages, cada vez que um novo banco de dados for criado no modelo será alterado. Por exemplo, se adicionarmos ou removermos propriedades da classe de entidade Product, o Entity Framework descartará o banco de dados existente e criará um novo. Claro, essa não é uma ótima opção, pois os dados também serão perdidos, então recomendo que você explore outras opções para herdar a classe inicializadora do banco de dados.
A classe inicializador de banco de dados pode ser criada conforme mostrado na listagem abaixo. Aqui estamos semeando a tabela de produtos com duas linhas. Para propagar os dados:
- Override Seed method
- Adicionar produto ao Context.Products
- Chame Context.SaveChanges()
using ProductApp.Core;
using System.Data.Entity;
namespace ProductApp.Infrastructure {
public class ProductInitalizeDB : DropCreateDatabaseIfModelChanges {
protected override void Seed(ProductContext context) {
context.Products.Add(
new Product { Id = 1, Name = "Rice", inStock = true, Price = 30 });
context.Products.Add(
new Product { Id = 2, Name = "Sugar", inStock = false, Price = 40 });
context.SaveChanges();
base.Seed(context);
}
}
}
Até agora, fizemos todo o trabalho relacionado ao Entity Framework Code First para criar o banco de dados. Agora vamos implementar uma interface IProductRepository do projeto Core em uma classe ProductRepository concreta.
Repository Class
Essa é a classe que executará operações de banco de dados na Entidade Produto. Nesta classe, implementaremos a interface IProductRepository do projeto Core. Vamos começar adicionando uma classe ProductRepository ao projeto de infraestrutura e implementar a interface IProductRepository. Para executar operações de banco de dados, vamos escrever consultas simples do LINQ to Entity. A classe de repositório do produto pode ser criada conforme mostrado na listagem abaixo:
using ProductApp.Core.Interfaces;
using System.Collections.Generic;
using System.Linq;
using ProductApp.Core;
namespace ProductApp.Infrastructure {
public class ProductRepository : IProductRepository {
ProductContext context = new ProductContext();
public void Add(Product p) {
context.Products.Add(p);
context.SaveChanges();
}
public void Edit(Product p) {
context.Entry(p).State = System.Data.Entity.EntityState.Modified;
}
public Product FindById(int Id) {
var result = (from r in context.Products where r.Id == Id select r).FirstOrDefault();
return result;
}
public IEnumerable GetProducts() {
return context.Products;
}
public void Remove(int Id) {
Product p = context.Products.Find(Id);
context.Products.Remove(p);
context.SaveChanges();
}
}
}
Até agora, criamos uma classe Data Context, uma classe Database Initializer e a classe Repository. Vamos construir o projeto de infraestrutura para garantir que tudo esteja no lugar. O projeto ProductApp.Infrastructure terá a aparência fornecida na imagem abaixo:

Agora terminamos de criar o projeto de infraestrutura. Escrevemos todas as classes relacionadas a operações de banco de dados dentro do projeto de infraestrutura e toda a lógica relacionada ao banco de dados está em um local central. Sempre que alguma alteração na lógica do banco de dados for necessária, precisamos alterar apenas o projeto de infraestrutura.
Projeto de teste
A maior vantagem do Padrão de Repositório é a capacidade de teste. Isso nos permite testar a unidade dos vários componentes sem ter dependências de outros componentes do projeto. Por exemplo, criamos a classe Repository que executa as operações do banco de dados para verificar a exatidão da funcionalidade, portanto, devemos testá-la por unidade. Também devemos ser capazes de escrever testes para a classe Repository sem qualquer dependência do projeto web ou da interface do usuário. Como estamos seguindo o Padrão de Repositório, podemos escrever Testes de Unidade para o projeto de Infraestrutura sem qualquer dependência do projeto MVC (UI).
Para escrever Testes de Unidade para a classe ProductRepository, vamos adicionar as seguintes referências no projeto Test.
- Referência do projeto ProductApp.Core
- Referência do projeto ProductApp.Infrastructure
- Entity Framework package
Para adicionar o Entity Framework, clique com o botão direito do mouse no projeto de teste e clique em Gerenciar Pacote Nuget. No Gerenciador de Pacotes Windows, pesquise Entity Framework e instale a versão estável mais recente.
Para adicionar uma referência do projeto ProductApp.Core, clique com o botão direito do mouse no projeto Teste e clique em Adicionar Referência. Na Janela de Referência, clique na guia Projeto e selecione ProductApp.Core.
Para adicionar uma referência do projeto ProductApp.Infrastructure, clique com o botão direito do mouse no projeto Teste e clique em Adicionar Referência. Na Janela de Referência, clique na guia Projeto e selecione ProductApp.Infrastructure.
Copiar a cadeia de conexão
O Visual Studio sempre lê o arquivo de configuração do projeto em execução. Para testar o projeto de infraestrutura, executaremos o projeto de teste. Portanto, a cadeia de conexão deve fazer parte do App.Config do projeto de teste. Vamos copiar e colar a cadeia de conexão do projeto de infraestrutura no projeto de teste.
Adicionamos todas as referências necessárias e copiamos a cadeia de conexão. Vamos em frente agora e configurar a classe de teste. Criaremos uma classe de teste com o nome ProductRepositoryTest. Test Initialize é a função executada antes que os testes sejam executados. Precisamos criar uma instância da classe ProductRepository e chamar a classe ProductDbInitalize para propagar os dados antes de executarmos os testes. O inicializador de teste pode ser escrito conforme mostrado na lista abaixo:
[TestClass]
public class ProductRepositoryTest {
ProductRepository Repo;
[TestInitialize]
public void TestSetup() {
ProductInitalizeDB db = new ProductInitalizeDB();
System.Data.Entity.Database.SetInitializer(db);
Repo = new ProductRepository();
}
}
Agora escrevemos o Inicializador de Teste. Agora, vamos escrever o primeiro teste para verificar se a classe ProductInitalizeDB propaga duas linhas na tabela Product ou não. Como é o primeiro teste que executaremos, ele também verificará se o banco de dados foi criado ou não. Então, essencialmente, estamos escrevendo um teste:
- Para verificar a criação do banco de dados
- Para verificar o número de linhas inseridas pelo método de semente do Inicializador do Banco de Dados do Produto
[TestMethod]
public void IsRepositoryInitalizeWithValidNumberOfData() {
var result = Repo.GetProducts();
Assert.IsNotNull(result);
var numberOfRecords = result.ToList().Count;
Assert.AreEqual(2, numberOfRecords);
}
Como você pode ver, estamos chamando a função Repository GetProducts() para buscar todos os Products inseridos durante a criação do banco de dados. Este teste está realmente verificando se GetProducts() funciona conforme o esperado ou não, e também verificando a criação do banco de dados. Na janela Gerenciador de Testes, podemos executar o teste para verificação.

Para executar o teste, primeiro compile o projeto de teste e, no menu superior, selecione Test->Windows-Test Explorer. No Gerenciador de Testes, encontraremos todos os testes listados. Selecione o teste e clique em Executar.
Vamos em frente e escrever mais um teste para verificar a operação Adicionar Produto no Repositório:
[TestMethod]
public void IsRepositoryAddsProduct() {
Product productToInsert =
new Product { Id = 3, inStock = true, Name = "Salt", Price = 17
};
Repo.Add(productToInsert);
// If Product inserts successfully,
// number of records will increase to 3
var result = Repo.GetProducts();
var numberOfRecords = result.ToList().Count;
Assert.AreEqual(3, numberOfRecords);
}
Para verificar a inserção do Produto, estamos chamando a função Adicionar no Repositório. Se o produto for adicionado com sucesso, o número de registros aumentará de 2 para 3 e estamos verificando isso. Ao executar o teste, descobriremos que o teste foi aprovado.

Dessa forma, podemos escrever testes para todas as operações do banco de dados da classe Product Repository. Agora temos certeza de que implementamos a classe Repository corretamente porque os testes estão passando, o que significa que o projeto Infrastructure e Core pode ser usado com qualquer projeto de interface do usuário (neste caso, MVC).
MVC ou Projeto Web
Finalmente, chegamos ao projeto MVC! Como o projeto Test, precisamos adicionar as seguintes referências
- Referência do projeto ProductApp.Core
- Referência do projeto ProductApp.Infrastructure
Para adicionar uma referência do projeto ProductApp.Core, clique com o botão direito do mouse no projeto MVC e clique em Adicionar Referência. Na Janela de Referência, clique na guia Projeto e selecione ProductApp.Core.
Para adicionar uma referência do projeto ProductApp.Infrastructure, clique com o botão direito do mouse no projeto MVC e clique em Adicionar Referência. Na Janela de Referência, clique na guia Projeto e selecione ProductApp.Infrastructure.
Copiar a cadeia de conexão
O Visual Studio sempre lê o arquivo de configuração do projeto em execução. Para testar o projeto de infraestrutura, executaremos o projeto de teste, portanto, a cadeia de conexão deve fazer parte do App.Config do projeto de teste. Para facilitar, vamos copiar e colar a cadeia de conexão do projeto de infraestrutura no projeto de teste.
Scaffolding do aplicativo
Devemos ter tudo no lugar para estruturar o controlador MVC. Para scaffold, clique com o botão direito do mouse na pasta Controller e selecione MVC 5 Controller with Views, usando o Entity Framework, conforme mostrado na imagem abaixo:

Em seguida, veremos a janela Adicionar controlador. Aqui, precisamos fornecer as informações da classe de contexto Model e Data Class. Em nosso projeto, a classe de modelo é a classe Product do projeto Core e a classe de contexto Data é a classe ProductDataContext do projeto Infrastructure. Vamos selecionar as duas classes no menu suspenso, conforme mostrado na imagem abaixo:

Além disso, devemos certificar-nos de que as opções Gerar Exibições, Bibliotecas de scripts de referência e Usar uma página de layout estejam selecionadas.
Ao clicar em Adicionar, o Visual Studio criará o ProductsController e os Modos de Exibição dentro da pasta Exibições/Produtos. O projeto MVC deve ter a estrutura mostrada na imagem abaixo:

Neste ponto, se formos em frente e executarmos o aplicativo, poderemos realizar operações CRUD na entidade Product.

Problema com andaimes
Mas ainda não terminamos! Vamos abrir a classe ProductsController e examinar o código. Na primeira linha, encontraremos o problema. Como usamos o scaffold MVC, o MVC está criando um objeto da classe ProductContext para executar as operações do banco de dados.

Todas as dependências na classe de contexto associam o projeto de interface do usuário e o banco de dados firmemente um ao outro. Como sabemos, a classe Datacontext é um componente do Entity Framework. Não queremos que o projeto MVC saiba qual tecnologia de banco de dados está sendo usada no projeto de infraestrutura. Por outro lado, não testamos a classe Datacontext; testamos a classe ProductRepository. Idealmente, devemos usar a classe ProductRepository em vez da classe ProductContext para executar operações de banco de dados no MVC Controller. Para resumir,
- O MVC Scaffolding usa a classe de contexto de dados para executar operações de banco de dados. A classe de contexto de dados é um componente do Entity Framework, portanto, seu uso associa fortemente a MVC (interface do usuário) com a tecnologia EF (Banco de Dados).
- A classe de contexto de dados não é testada por unidade, portanto, não é uma boa ideia usá-la.
- Temos uma classe ProductRepository testada. Devemos usar isso dentro do Controller para realizar operações de banco de dados. Além disso, a classe ProductRepository não expõe a tecnologia de banco de dados à interface do usuário.
Para usar a classe ProductRepository para operações de banco de dados, precisamos refatorar a classe ProductsController. Para isso, há dois passos que precisamos seguir:
- Crie um objeto da classe ProductRepository em vez da classe ProductContext.
- Chame métodos da classe ProductRepository para executar operações de banco de dados na entidade Product em vez de métodos da classe ProductContext.
Na listagem abaixo, comentei códigos usando ProductContext e chamados métodos ProductRepository. Após a refatoração, a classe ProductController terá a seguinte aparência:
using System;
using System.Net;
using System.Web.Mvc;
using ProductApp.Core;
using ProductApp.Infrastructure;
namespace ProductApp.Web.Controllers {
public class ProductsController : Controller {
// private ProductContext db = new ProductContext();
private ProductRepository db = new ProductRepository();
public ActionResult Index() {
// return View(db.Products.ToList());
return View(db.GetProducts());
}
public ActionResult Details(int? id) {
if (id == null) {
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// Product product = db.Products.Find(id);
Product product = db.FindById(Convert.ToInt32(id));
if (product == null) {
return HttpNotFound();
}
return View(product);
}
public ActionResult Create() {
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(
[Bind(Include = "Id,Name,Price,inStock")] Product product) {
if (ModelState.IsValid) {
// db.Products.Add(product);
// db.SaveChanges();
db.Add(product);
return RedirectToAction("Index");
}
return View(product);
}
public ActionResult Edit(int? id) {
if (id == null) {
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Product product = db.FindById(Convert.ToInt32(id));
if (product == null) {
return HttpNotFound();
}
return View(product);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(
[Bind(Include = "Id,Name,Price,inStock")] Product product) {
if (ModelState.IsValid) {
// db.Entry(product).State = EntityState.Modified;
// db.SaveChanges();
db.Edit(product);
return RedirectToAction("Index");
}
return View(product);
}
public ActionResult Delete(int? id) {
if (id == null) {
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Product product = db.FindById(Convert.ToInt32(id));
if (product == null) {
return HttpNotFound();
}
return View(product);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id) {
// Product product = db.FindById(Convert.ToInt32(id));
// db.Products.Remove(product);
// db.SaveChanges();
db.Remove(id);
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing) {
if (disposing) {
// db.Dispose();
}
base.Dispose(disposing);
}
}
}
Após a refatoração, vamos em frente e construir e executar o aplicativo – devemos ser capazes de fazer isso e executar as operações CRUD.
Injetando a dependência
Agora estamos felizes que o aplicativo esteja instalado e funcionando e tenha sido criado usando o padrão Repository. Mas ainda há um problema: estamos criando diretamente um objeto da classe ProductRepository dentro da classe ProductsController e não queremos isso. Queremos inverter a dependência e delegar a tarefa de injetar a dependência a um terceiro, popularmente conhecido como contêiner de DI. Essencialmente, ProductsController solicitará que o contêiner de DI retorne a instância de IProductRepository.
Há muitos contêineres de DI disponíveis para aplicativos MVC. Neste exemplo, usaremos o contêiner de DI do Unity mais simples. Para fazer isso, clique com o botão direito do mouse no projeto MVC e clique em Gerenciar Pacote Nuget. No Gerenciador de Pacotes NuGet, pesquise Unity.Mvc e instale o pacote.

Depois que o pacote Unity.Mvc estiver instalado, vamos abrir uma pasta App_Start. Dentro da pasta App_Start, encontraremos o arquivo UnityConfig.cs. Na classe UnityConfig, temos que registrar o tipo. Para fazer isso, abra a função RegisterTypes na classe UnityConfig e registre o tipo conforme mostrado na listagem abaixo:
public static void RegisterTypes(IUnityContainer container) {
// TODO: Register your types here
container.RegisterType<iproductrepository, productrepository = "">();
}
Registramos o tipo no contêiner de DI do Unity. Agora vamos fazer um pouco de refatoração na classe ProductsController. No construtor de ProductsController, passaremos a referência para a interface do repositório. Sempre que exigido pelo aplicativo, o contêiner de DI do Unity injetará o objeto concreto de ProductRepository no aplicativo resolvendo o tipo. Precisamos refatorar o ProductsController conforme mostrado na listagem abaixo:
public class ProductsController : Controller {
IProductRepository db;
public ProductsController(IProductRepository db) {
this.db = db;
}
Vamos em frente e construir e executar o aplicativo. Devemos ter o aplicativo instalado e funcionando e devemos ser capazes de realizar operações CRUD usando o Padrão de Repositório e a Injeção de Dependência!
Conclusão
Neste artigo, aprendemos passo a passo como criar uma aplicação MVC seguindo o padrão Repository. Ao fazer isso, podemos colocar toda a lógica do banco de dados em um só lugar e, sempre que necessário, precisamos apenas alterar o repositório e testá-lo. O Padrão de Repositório também acopla livremente a interface do usuário do aplicativo com a lógica do Banco de Dados e as entidades de Domínio e torna seu aplicativo mais testável.
Além disso, não se esqueça de verificar Ignite UI, que você pode usar com HTML5, Angular, React ou ASP.NET MVC para criar aplicativos avançados da Internet. Obrigado por ler!
