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:


José Carlos Macoratti