.NET

25 nov, 2015

ASP .NET MVC – Injeção de dependência e repositório Mock

Publicidade

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; vou mostrar também como criar um repositório Mock usando o Moq.

Conceitos

A injeção de dependência (DI) é um padrão de projeto cujo objetivo é manter um baixo acoplamento entre diferentes módulos de um sistema.Nesta solução, as dependências entre os módulos não são definidas programaticamente, mas sim pela configuração de uma infraestrutura de software (container) que é responsável por “injetar” em cada componente suas dependências declaradas.

A injeção de dependência se relaciona com o padrão Inversão de Controle, mas não pode ser considerada um sinônimo deste (fonte).

Em suma, a DI isola a implementação de um objeto da construção do objeto do qual ele depende.

Podemos implementar a injeção de dependência das seguintes maneiras:

  • Injeção via Construtor;
  • Injeção via Propriedades (get/set);
  • Injeção via Interface;
  • Injeção usando um framework(Spring/Unity/Ninject).

Na programação orientada a objeto, objetos Mock ou fictícios são objetos simulados que imitam o comportamento de objetos reais. Os objetos Mocks são geralmente usados em testes de unidade.

Assim, os objetos Mock são criados para testar o comportamento de algum outro objeto(real); com isso, estamos mocando, ou seja, simulando ou fingindo o objeto real e fazendo algumas operações de forma controlada de modo que o resultado retornado (teste) é sempre válido.

Após definir a injeção de dependência usando o Ninject, vamos criar repositório abstrato e, em seguida, definir uma implementação mock do nosso repositório usando a ferramenta MOQ.

O que é MOQ?

Moq é uma biblioteca para mocar objetos para a plataforma .NET desenvolvida para tirar o máximo proveito de recursos como Linq, árvores de expressão, expressões lambdas etc.

Recursos usados:

Criando o projeto ASP .NET MVC no VS Community 2013

Nota: Em uma aplicação de produção, adotaríamos uma abordagem mais robusta criando uma solução no Visual Studio com três ou mais projetos, onde um projeto seria usado como Model, o outro seria a nossa aplicação MVC e o terceiro projeto seria usado para testes unitários (marcando a opção Add unit Tests).

Abra o VS 2013 Community e clique em New Project e, a seguir, selecione Visual C# -> Web -> ASP .NET Web Application. Depois informe o nome Mvc_Ninject_Moq e clique no botão OK:

mvc_idmock11

A seguir, selecione o template Empty, marque MVC e clique no botão OK.

mvc_ninj11

Será criado um projeto ASP .NET MVC vazio com a estrutura básica para criarmos o nosso exemplo.

mvc_idmock12

Instalando o Ninject e o MOQ em nossa solução

Antes de continuar, temos que incluir a referência ao Ninject e ao Moq em nosso projeto usando o Nuget.

No menu TOOLS, clique em Nuget Package Manager -> Manage Nuget Packages for Solution. Na janela, procure por Ninject e instale o item referente ao Ninject MVC5 clique no botão Install.

mvc_ninj12

Se preferir usar o Package Manager Console, digite o seguinte comando no console:  Install-Package Ninject.MVC5.

Observe que após a conclusão da instalação do pacote do Ninject, foi criado na pasta App_Start o arquivo NinjectWebCommon.cs, que usaremos para configurar a injeção da dependência em nosso projeto.

mvc_ninj19

Agora vamos incluir uma referência a biblioteca MOQ em nosso projeto via Nuget.

No menu TOOLS, clique em Nuget Package Manager -> Manage Nuget Packages for Solution.

Digite o texto MOQ para localizar o pacote e, a seguir, selecione e clique no botão Install ao lado do pacote:

net_mock14

Se você preferir, pode usar o console. Para isso, no menu TOOLS, clique em Nuget Package Manager -> Package Manager Console. No console digite o seguinte comando: Install-Package Moq. Ao final, você verá na janela Solution Explorer as referências ao Moq e Ninject instaladas em nosso projeto:

mvc_idmock13

Configurando o container de Injeção de Dependência

Vamos criar uma pasta em nosso projeto chamada Infraestrutura, para configurar o container Ninject de forma que nossa aplicação MVC irá usar para instanciar os objetos na aplicação.

Clique com o botão direito sobre o nome do projeto e, a seguir, clique em Add -> New Folder e informe o nome Infraestrutura.

Selecione a pasta Infraestrutura criada e, no menu PROJECT, clique em Add Class, informe o nome NinjectDependencyResolver e clique no botão Add.

mvc_idmock14

A seguir, inclua o código abaixo para a classe NinjectDependencyResolver:

using System;
using System.Collections.Generic;
using Ninject;
using System.Web.Mvc;
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()
        {
            //defina as vinculações aqui
        }
    }
}

Agora precisamos criar ‘uma ponte’ entre esta classe e o suporte MVC para a injeção de dependência no arquivo App_Start/NinjectWebCommon.cs que foi adicionado pelo Ninject em nosso projeto.

Abra o arquivo NinjectWebCommon.cs e defina o código abaixo no método RegisterServices:

....
        ....
        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            System.Web.Mvc.DependencyResolver.SetResolver(new Mvc_Ninject_Moq.Infraestrutura.NinjectDependencyResolver(kernel));
        }      
     }
  }

Obs: Estou mostrando apenas parte do código na classe NinjectWebCommon, onde incluímos a linha em azul.

Definindo o Model

Precisamos, agora, definir um model para que nossa aplicação possa ter o que consumir. Neste exemplo, eu vou criar uma classe Usuario com uma estrutura bem simples para simular um cadastramento.

Selecione a pasta Models e no menu PROJECT, clique em Add Class e informe o nome Usuario. A seguir, clique no botão Add. Depois digite o código abaixo definindo três propriedades na classe Usuario:

  • Nome

  • Sobrenome

  • E-mail

mvc_mdlst13

Observe que definimos o namespace System.Componente.DataAnnotations para poder aplicar os atributos de validação: Required, StringLength e Display ao nosso modelo e, assim, realizar a validação do formulário quando do envio dos dados ao servidor.

Criando o controlador

Agora eu vou criar o nosso repositório e vou fazer isso na pasta Models para tornar o exemplo mais simples. Uma abordagem mais adequada seria criar o repositório em outro projeto ou em uma outra pasta na aplicação MVC.

Selecione a pasta Models e no menu PROJECT clique em Add New Item, clique na guia Code e no template Interface e informe o nomeIProdutoRepositorio e clique no botão Add.

mvc_idmock16

A seguir, inclua o código abaixo para a interface IProdutoRepositorio:

using System.Collections.Generic;
namespace Mvc_Ninject_Moq.Models
{
    public interface IProdutoRepositorio
    {
        IEnumerable<Produto> Produtos { get; }
    }
}

Nossa interface é bem simples e usa a interface IEnumerable<T> para permitir uma sequência de objetos Produto a quem chamar o método Produtos.

Essa interface deverá ser implementada por uma classe concreta e a classe que depende dessa interface poderá obter objetos Produto sem a necessidade de saber nada sobre de onde os objetos estão vindo ou como a classe de implementação vai enviar os objetos.

Na segunda parte do artigo, eu vou criar o repositório Mock, o controlador e a view para exibir uma lista de produtos em nossa aplicação MVC.

Pegue a primeira parte do projeto aqui: Mvc_Ninject_Moq_1.zip