Neste artigo vou mostrar como usar a ferramenta StructureMap para realizar a injeção de dependência em uma aplicação ASP .NET MVC 5. O StructureMap é a ferramenta mais antiga para realizar a injeção de dependência para a plataforma .NET.
Antes de começar, vamos recordar alguns conceitos:
Dependency Inversion Principle (DIP)
- Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstraçõe;
- Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações.
O DIP nos ajuda a desenvolver um código com baixo acoplamento fazendo com que módulos de alto nível dependam de abstrações e não de implementações concretas de módulos de baixo nível.
Indo direto ao ponto: dependa de interfaces e não de classe concretas.
O padrão Inversion of Control é uma implementação deste princípio.
Inversion of Control (IoC)
O termo Inversion of Control (Ioc) se refere a um estilo de programação onde um framework controla o fluxo do programa alterando o controle na sua forma normal.
Dependency Injection (DI)
É um processo de passar os detalhes da abstração para uma entidade
- A inversão de controle (Ioc) é um princípio e a injeção de dependência (ID) é uma forma de implementar a inversão de controle, ou seja: geralmente fazemos a inversão de controle utilizando a injeção de dependência;
- A DIP é um princípio que nos guia para a DI através da Ioc .
Recursos usados: Visual Studio Community 2015.
Nota: baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão profissional.
Criando o projeto no VS Community
Abra o VS 2015 Community e clique em New Project. Depois selecione a linguagem Visual C# e o template ASP .NET Web Applications. Em seguida, informe o nome da solução como Mvc_StructureMap e clique no botão OK.
Selecione o template Empty e marque a opção MVC, definindo as opções conforme a figura abaixo e clique no botão OK:
No menu Tools, clique em Nuget Package Manager -> Manage Nugect Packages for Solution. Selecione a biblioteca StructureMap.MVC4 e clique no botão Install.
Ao final teremos os pacotes referenciados no projeto e as seguintes alterações feitas na estrutura do projeto:
Na pasta DependencyResolution, o arquivo Ioc.cs é o mais importante.
using StructureMap; using StructureMap.Graph; namespace Mvc_StructureMap.DependencyResolution { public static class IoC { public static IContainer Initialize() { ObjectFactory.Initialize(x => { x.Scan(scan => { scan.TheCallingAssembly(); scan.WithDefaultConventions(); }); // x.For<IExample>().Use<Example>(); }); return ObjectFactory.Container; } } }
Ao abri-lo, você vai ver um único método de inicialização onde você irá configurar as suas interfaces e os tipos que devem ser usados por eles para esta aplicação.
Não vamos alterar nada neste arquivo.
Fazendo a injeção de dependência com o StructureMap
Para testar a injeção de dependência usando o StructureMap, precisamos dos seguintes ingredientes:
- A definição de uma interface;
- Uma implementação dessa interface;
- A criação de um controlador que usar a interface;
- A criação da View;
- Testar a aplicação.
Vamos criar uma interface IMensagem na pasta Models do projeto com o código abaixo:
namespace Mvc_StructureMap.Models { public interface IMensagem { string GetMensagem(); } }
Ainda na pasta Models, vamos criar a classe concreta Mensagem que implementará esta interface:
namespace Mvc_StructureMap.Models { public class Mensagem : IMensagem { public string GetMensagem() { return "Testando a injeção de dependência com o StructureMap"; } } }
Agora vamos criar o controlador HomeController na pasta Controllers usando o Scaffold MVC 5 Controller Empty:
using Mvc_StructureMap.Models; using System.Web.Mvc; namespace Mvc_StructureMap.Controllers { public class HomeController : Controller { private readonly IMensagem _mensagem; public HomeController(IMensagem mensagem) { _mensagem = mensagem; } // GET: Home public ActionResult Index() { ViewBag.Mensagem = _mensagem.GetMensagem(); return View(); } } }
Neste código vamos fazer a injeção de dependência no controlador usando o construtor.
Precisamos de mais alguma coisa? Não, então vamos testar.
Executando o projeto iremos obter o seguinte resultado:
using StructureMap; using WebApplication1.Controllers; namespace WebApplication1.DependencyResolution { public static class IoC { public static IContainer Initialize() { ObjectFactory.Initialize(x => { x.For<IDependencia>().Use<Dependencia>(); }); return ObjectFactory.Container; } } }
Pegue o projeto completo aqui: Mvc_StructureMap.zip