ASP .NET MVC - Injeção de dependência e Repositório Mock - II
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 Mock
Abra 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 esta 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;
using Moq;
using Mvc_Ninject_Moq.Models;
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()
{
Mock<IProdutoRepositorio> mock = new Mock<IProdutoRepositorio>();
mock.Setup(m => m.Produtos).Returns(new List<Produto>
{
new Produto { Nome = "Teclado sem fio", Preco = 130 },
new Produto { Nome = "Mouse Otico", Preco = 40 },
new Produto { Nome = "Microfone", Preco = 15 },
new Produto { Nome = "Pen Drive 8 GB", Preco = 59 },
new Produto { Nome = "Fones de Ouvido", Preco = 19 }
});
kernel.Bind<IProdutoRepositorio>().ToConstant(mock.Object);
}
}
}
|
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.
Exibindo uma lista de Produtos
Vamos 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 um 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. Passando uma lista de objetos para o método View fornece ao framework com dados com o qual 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 onde definimos o model como sendo do tipo IEnumerable<Produto> pois é esses 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
Disse Jesus : "Uma geração má e
adúltera pede um sinal, e nenhum sinal lhe será dado, senão o sinal do profeta
Jonas. E, deixando-os, retirou-se."
Mateus 16:4
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
.NET - Inversão de controle e Injeção de dependência para ...