ASP .NET MVC – Injeção de dependência e repositório Mock – Parte 02
Veja como podemos usar o container Ninject para realizar a injeção de dependência em uma aplicação ASP .NET MVC 5 e criar um repositório Mock usando o Moq.
No artigo de hoje, eu vou mostrar como podemos usar o container Ninject para realizar a injeção de dependência em uma aplicação ASP .NET MVC 5 e criar um repositório Mock usando o Moq.
Na primeira parte do artigo, criamos a solução, referenciamos o Ninject e o MOQ, configuramos o container Ninject e criamos o nosso model Produto e o nosso repositório IProdutoRepositorio.
Vamos agora criar o repositório Mock, o controlador e a view para exibir uma lista de produtos em nossa aplicação MVC usando o repositório mock.
Na figura abaixo, podemos visualizar o nosso projeto e a implementação da interface IProdutoRepositorio.cs que fizemos na primeira parte do artigo.
Recursos usados:
Criando o repositório MockAbra o VS 2013 Community e clique em Open Project.
A seguir, selecione o projeto Mvc_Ninject_Moq criado na primeira parte deste artigo.
Como já definimos uma interface para o nosso repositório, podemos implementar o mecanismo de persistência vinculando-o ao nosso banco de dados. Antes de fazer isso, vamos criar uma implementação do repositório mock para a interface IProdutoRepositorio.
Vamos definir uma implementação mock vinculando-a à interface IProdutoRepositorio no método AddBindings da classe NinjectDependencyResolver que está na pasta infraestrutura do nosso projeto.
A seguir, temos o código da classe NinjectDependencyResolver onde as linhas em azul representam o código que incluímos para implementar o repositório.
Incluímos a referência ao Moq e a ao nosso Model e incluímos o código no método AddBindings:
using System;
using System.Collections.Generic;
using Ninject;
using System.Web.Mvc;
<span style="color: #0000ff;">using Moq;</span>
<span style="color: #0000ff;">using Mvc_Ninject_Moq.Models;</span>
namespace Mvc_Ninject_Moq.Infraestrutura
{
public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
<span style="color: #0000ff;">Mock<IProdutoRepositorio> mock = new Mock<IProdutoRepositorio>();</span>
<span style="color: #0000ff;"> mock.Setup(m => m.Produtos).Returns(new List<Produto> </span>
<span style="color: #0000ff;"> {</span>
<span style="color: #0000ff;"> new Produto { Nome = "Teclado sem fio", Preco = 130 },</span>
<span style="color: #0000ff;"> new Produto { Nome = "Mouse Otico", Preco = 40 },</span>
<span style="color: #0000ff;"> new Produto { Nome = "Microfone", Preco = 15 },</span>
<span style="color: #0000ff;"> new Produto { Nome = "Pen Drive 8 GB", Preco = 59 },</span>
<span style="color: #0000ff;"> new Produto { Nome = "Fones de Ouvido", Preco = 19 }</span>
<span style="color: #0000ff;"> });</span>
<span style="color: #0000ff;"> kernel.Bind<IProdutoRepositorio>().ToConstant(mock.Object);</span>
}
}
}
O que fizemos aqui vai permitir que o Ninject retorne o mesmo objeto mock sempre que uma requisição para a implementação da interface IProdutoRepositorio for feita; foi por isso que usamos o método ToConstant para definir o escopo do Ninject:
kernel.Bind<IProdutoRepositorio>().ToConstant(mock.Object);
Assim, ao invés de criar uma nova instância da implementação do objeto a cada vez o Ninject sempre responder a requisição para a interface IProdutoRepositorio usando o mesmo objeto mock. VER COM RINA ESSA FRASE
Exibindo uma lista de produtosVamos criar um controlador e um método Action para pode exibir detalhes dos produtos no repositório e vamos usar o repositório mock.
Clique com o botão direito sobre a pasta Controllers do projeto MVC e selecione Add -> Controller.
Selecione o Scaffold – MVC 5 Controller – Empty e clique no botão Add.
Informe o nome ProdutoController para o controlador e clique no botão Add.
A seguir, remova o método Action Index criado por padrão e inclua um construtor no controlador declarando uma dependência para com a interface IProdutoRepositorio.
Fazendo assim, forçamos o Ninject a injetar a dependência para o repositório produto quando ele instanciar a classe ProdutoController.
Para poder exibir os produtos, crie um método Action chamado ListaProdutos() que irá renderizar a view:
using System.Web.Mvc;
using Mvc_Ninject_Moq.Models;
namespace Mvc_Ninject_Moq.Controllers
{
public class ProdutoController : Controller
{
private IProdutoRepositorio repositorio;
public ProdutoController(IProdutoRepositorio produtoRepositorio)
{
this.repositorio = produtoRepositorio;
}
public ViewResult ListaProdutos()
{
return View(repositorio.Produtos);
}
}
}
Note que estamos chamando o método View sem especificar um nome para view. Fazendo assim, o framework irá renderizar a view default para o método Action. Passar uma lista de objetos para o método View fornece ao framework dados com os quais ele pode popular objeto Model em uma view fortemente tipada.
Agora vamos incluir uma view default para o método Action ListaProdutos().
Clique com o botão direito no método ListaProdutos() do controlador ProdutoController e selecione Add View.
Defina o nome da view como ListaProdutos, selecione o template Empty e o Model Class Produto conforme mostra a figura abaixo e clique no botão Add.
Será criado o arquivo ListaProduto.cshtml na pasta Views/Produto.
Vamos abrir esse arquivo e ajustar o código conforme mostrado abaixo:
@using Mvc_Ninject_Moq.Models
@model IEnumerable<Produto>
@{
ViewBag.Title = "Produtos";
}
<h2>Lista de Produtos</h2>
@foreach (var p in Model)
{
<div>
<h3>@p.Nome</h3>
@p.Descricao
<h4>@p.Preco.ToString("c")</h4>
</div>
}
Alteramos o código gerado por padrão no qual definimos o model como sendo do tipo IEnumerable<Produto>, pois é esse o tipo que o controlador irá obter do repositório e passar para a view.
Exibimos o preço usando a formatação ToString(“c”) que irá renderizar os valores numéricos como moeda de acordo com as configurações locais.
Vamos agora fazer alguns pequenos ajustes no arquivo _layout.cshtml na pasta Views/Shared e finalmente, antes de executar o projeto, vamos alterar a roda definida no arquivo RouteConfig.cs na pasta App_Start.
Abra o arquivo RouteConfig.cs e altere a rota conforme mostra o código abaixo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace Mvc_Ninject_Moq
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Produto", action = "ListaProdutos", id = UrlParameter.Optional }
);
}
}
}
Agora podemos executar o projeto e iremos obter a nossa lista de produtos usando o Ninject e um repositório mock.
Podemos melhorar a apresentação usando o BootStrap, mas deixo isso como uma tarefa para você.
Pegue o projeto completo aqui: Mvc_Ninject_Moq_2.zip.













