Injeção de dependência do ASP.NET MVC 4

Por Equipe de Campos da Web

Baixar o Kit de Treinamento do Web Camps

Este Laboratório Prático pressupõe que você tenha conhecimento básico dos filtros MVC ASP.NET e ASP.NET MVC 4. Se você não tiver usado filtros ASP.NET MVC 4 antes, recomendamos que você acesse ASP.NET Laboratório prático de Filtros de Ação Personalizada do MVC .

Observação

Todos os snippets e código de exemplo estão incluídos no Kit de Treinamento de Campos da Web, disponível em Versões do Microsoft-Web/WebCampTrainingKit. O projeto específico para este laboratório está disponível em ASP.NET Injeção de Dependência MVC 4.

No paradigma programação orientada a objetos, os objetos trabalham juntos em um modelo de colaboração em que há colaboradores e consumidores. Naturalmente, esse modelo de comunicação gera dependências entre objetos e componentes, tornando-se difícil de gerenciar quando a complexidade aumenta.

Dependências de classe e complexidade do modelo

Dependências de classe e complexidade do modelo

Você provavelmente já ouviu falar sobre o Padrão de Fábrica e a separação entre a interface e a implementação usando serviços, em que os objetos cliente geralmente são responsáveis pelo local do serviço.

O padrão de Injeção de Dependência é uma implementação específica da Inversão de Controle. A inversão de controle (IoC) significa que os objetos não criam outros objetos nos quais dependem para realizar seu trabalho. Em vez disso, eles obtêm os objetos de que precisam de uma origem externa (por exemplo, um arquivo de configuração xml).

A DI (Injeção de Dependência) significa que isso é feito sem a intervenção do objeto, geralmente por um componente de estrutura que passa parâmetros de construtor e define propriedades.

O padrão de design di (injeção de dependência)

Em um alto nível, o objetivo da Injeção de Dependência é que uma classe cliente (por exemplo, o golfista) precise de algo que satisfaça uma interface (por exemplo, IClub). Ele não se importa com o tipo concreto (por exemplo , WoodClub, IronClub, WedgeClub ou PutterClub), ele quer que outra pessoa lide com isso (por exemplo, um bom caddy). O Resolvedor de Dependência no ASP.NET MVC pode permitir que você registre sua lógica de dependência em outro lugar (por exemplo, um contêiner ou um recipiente de clubes).

Ilustração da injeção de dependência do diagrama

Injeção de dependência – analogia de golfe

As vantagens de usar o padrão de Injeção de Dependência e a Inversão de Controle são as seguintes:

  • Reduz o acoplamento de classe
  • Aumenta a reutilização de código
  • Melhora a capacidade de manutenção de código
  • Aprimora o teste de aplicativo

Observação

Às vezes, a Injeção de Dependência é comparada com o Padrão de Design de Fábrica Abstrato, mas há uma pequena diferença entre ambas as abordagens. A DI tem uma Estrutura funcionando atrás para resolver dependências chamando as fábricas e os serviços registrados.

Agora que você entende o Padrão de Injeção de Dependência, aprenderá em todo este laboratório como aplicá-lo no ASP.NET MVC 4. Você começará a usar a Injeção de Dependência nos Controladores para incluir um serviço de acesso ao banco de dados. Em seguida, você aplicará a Injeção de Dependência aos Modos de Exibição para consumir um serviço e mostrar informações. Por fim, você estenderá a DI para ASP.NET filtros MVC 4, injetando um filtro de ação personalizado na solução.

Neste laboratório prático, você aprenderá a:

  • Integrar ASP.NET MVC 4 ao Unity para injeção de dependência usando pacotes NuGet
  • Usar injeção de dependência dentro de um controlador MVC ASP.NET
  • Usar injeção de dependência dentro de um modo de exibição MVC ASP.NET
  • Usar injeção de dependência dentro de um filtro de ação ASP.NET MVC

Observação

Este Laboratório está usando o Pacote NuGet unity.Mvc3 para resolução de dependência, mas é possível adaptar qualquer Estrutura de Injeção de Dependência para trabalhar com ASP.NET MVC 4.

Pré-requisitos

Você deve ter os seguintes itens para concluir este laboratório:

Configuração

Instalando snippets de código

Por conveniência, grande parte do código que você gerenciará ao longo deste laboratório está disponível como snippets de código do Visual Studio. Para instalar os snippets de código, execute o arquivo .\Source\Setup\CodeSnippets.vsi .

Se você não estiver familiarizado com os snippets de Visual Studio Code e quiser aprender a usá-los, consulte o apêndice deste documento "Apêndice B: Usando snippets de código".


Exercícios

Este Hands-On Lab é composto pelos seguintes exercícios:

  1. Exercício 1: injetando um controlador
  2. Exercício 2: Injetando uma exibição
  3. Exercício 3: Injetando filtros

Observação

Cada exercício é acompanhado por uma pasta End que contém a solução resultante que você deve obter depois de concluir os exercícios. Você pode usar essa solução como um guia se precisar de ajuda adicional para trabalhar nos exercícios.

Tempo estimado para concluir este laboratório: 30 minutos.

Exercício 1: injetando um controlador

Neste exercício, você aprenderá a usar a Injeção de Dependência em ASP.NET controladores MVC integrando o Unity usando um Pacote NuGet. Por esse motivo, você incluirá serviços em seus controladores MvcMusicStore para separar a lógica do acesso aos dados. Os serviços criarão uma nova dependência no construtor do controlador, que será resolvida usando a Injeção de Dependência com a ajuda do Unity.

Essa abordagem mostrará como gerar aplicativos menos acoplados, que são mais flexíveis e fáceis de manter e testar. Você também aprenderá a integrar ASP.NET MVC ao Unity.

Sobre o Serviço StoreManager

O Repositório de Músicas do MVC fornecido na solução begin agora inclui um serviço que gerencia os dados do Controlador de Repositório chamado StoreService. Abaixo, você encontrará a implementação do Serviço de Loja. Observe que todos os métodos retornam entidades de modelo.

namespace MvcMusicStore.Controllers
{    
    using System.Web.Mvc;
    using MvcMusicStore.Filters;
    using MvcMusicStore.Services;

    [MyNewCustomActionFilter(Order = 1)]
    [CustomActionFilter(Order = 2)]
    public class StoreController : Controller
    {
        private IStoreService service;

        public StoreController(IStoreService service)
        {
            this.service = service;
        }

        // GET: /Store/
        public ActionResult Details(int id)
        {
            var album = this.service.GetAlbum(id);
            if (album == null)
            {
                return this.HttpNotFound();
            }

            return this.View(album);
        }

        public ActionResult Browse(string genre)
        {
            // Retrieve Genre and its Associated Albums from database
            var genreModel = this.service.GetGenreByName(genre);

            return this.View(genreModel);
        }

        public ActionResult Index()
        {
            var genres = this.service.GetGenres();

            return this.View(genres);
        }

        // GET: /Store/GenreMenu
        public ActionResult GenreMenu()
        {
            var genres = this.service.GetGenres();

            return this.PartialView(genres);
        }
    }
}

StoreController da solução begin agora consome StoreService. Todas as referências de dados foram removidas do StoreController e agora é possível modificar o provedor de acesso a dados atual sem alterar nenhum método que consuma StoreService.

Você verá abaixo que a implementação StoreController tem uma dependência com StoreService dentro do construtor de classe.

Observação

A dependência introduzida neste exercício está relacionada à Inversão de Controle (IoC).

O construtor de classe StoreController recebe um parâmetro de tipo IStoreService , que é essencial para executar chamadas de serviço de dentro da classe . No entanto, StoreController não implementa o construtor padrão (sem parâmetros) que qualquer controlador deve ter que trabalhar com ASP.NET MVC.

Para resolve a dependência, o controlador precisa ser criado por uma fábrica abstrata (uma classe que retorna qualquer objeto do tipo especificado).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcMusicStore.ViewModels;
using MvcMusicStore.Models;
using MvcMusicStore.Services;

namespace MvcMusicStore.Controllers
{
    public class StoreController : Controller
    {
        private IStoreService service;

        public StoreController(IStoreService service)
        {
            this.service = service;
        }

        //
        // GET: /Store/
        public ActionResult Index()
        {
            // Create list of genres
            var genres = this.service.GetGenreNames();

            // Create your view model
            var viewModel = new StoreIndexViewModel
            {
                Genres = genres.ToList(),
                NumberOfGenres = genres.Count()
            };

            return View(viewModel);
        }

        //
        // GET: /Store/Browse?genre=Disco
        public ActionResult Browse(string genre)
        {
            var genreModel = this.service.GetGenreByName(genre);

            var viewModel = new StoreBrowseViewModel()
            {
                Genre = genreModel,
                Albums = genreModel.Albums.ToList()
            };

            return View(viewModel);
        }

        //
        // GET: /Store/Details/5
        public ActionResult Details(int id)
        {
            var album = this.service.GetAlbum(id);

            return View(album);
        }
    }
}

Observação

Você receberá um erro quando a classe tentar criar o StoreController sem enviar o objeto de serviço, pois não há nenhum construtor sem parâmetros declarado.

Tarefa 1 – Executando o aplicativo

Nesta tarefa, você executará o aplicativo Begin, que inclui o serviço no Controlador da Loja que separa o acesso aos dados da lógica do aplicativo.

Ao executar o aplicativo, você receberá uma exceção, pois o serviço do controlador não é passado como um parâmetro por padrão:

  1. Abra a solução Begin localizada em Source\Ex01-Injecting Controller\Begin.

    1. Você precisará baixar alguns pacotes NuGet ausentes antes de continuar. Para fazer isso, clique no menu Projeto e selecione Gerenciar Pacotes NuGet.

    2. Na caixa de diálogo Gerenciar Pacotes NuGet , clique em Restaurar para baixar pacotes ausentes.

    3. Por fim, crie a solução clicando em Compilar | solução de build.

      Observação

      Uma das vantagens de usar o NuGet é que você não precisa enviar todas as bibliotecas em seu projeto, reduzindo o tamanho do projeto. Com o NuGet Power Tools, especificando as versões do pacote no arquivo Packages.config, você poderá baixar todas as bibliotecas necessárias na primeira vez que executar o projeto. É por isso que você precisará executar essas etapas depois de abrir uma solução existente deste laboratório.

  2. Pressione Ctrl + F5 para executar o aplicativo sem depuração. Você receberá a mensagem de erro "Nenhum construtor sem parâmetros definido para este objeto":

    Erro ao executar ASP.NET erro de aplicativo Iniciar MVC

    Erro ao executar ASP.NET Aplicativo De Início do MVC

  3. Feche o navegador.

Nas etapas a seguir, você trabalhará na Solução da Music Store para injetar a dependência de que esse controlador precisa.

Tarefa 2 – Incluindo o Unity na Solução MvcMusicStore

Nesta tarefa, você incluirá o Pacote NuGet Unity.Mvc3 para a solução.

Observação

O pacote Unity.Mvc3 foi projetado para ASP.NET MVC 3, mas é totalmente compatível com ASP.NET MVC 4.

O Unity é um contêiner de injeção de dependência leve e extensível com suporte opcional para interceptação de tipo e instância. É um contêiner de uso geral para uso em qualquer tipo de aplicativo .NET. Ele fornece todos os recursos comuns encontrados em mecanismos de injeção de dependência, incluindo: criação de objeto, abstração de requisitos especificando dependências em runtime e flexibilidade, adiando a configuração do componente para o contêiner.

  1. Instale o Pacote NuGet Unity.Mvc3 no projeto MvcMusicStore . Para fazer isso, abra o Console do Gerenciador de Pacotes em Exibir | Outras Janelas.

  2. Execute o comando a seguir.

    PMC

    Install-Package Unity.Mvc3
    

    Instalando o pacote NuGet Unity.Mvc3

    Instalando o pacote NuGet Unity.Mvc3

  3. Depois que o pacote Unity.Mvc3 for instalado, explore os arquivos e pastas que ele adiciona automaticamente para simplificar a configuração do Unity.

    Unity.Mvc3 instaladoPacote

    Pacote Unity.Mvc3 instalado

Tarefa 3 – Registrar o Unity em Global.asax.cs Application_Start

Nesta tarefa, você atualizará o método Application_Start localizado em Global.asax.cs para chamar o inicializador do Bootstrapper do Unity e, em seguida, atualizará o arquivo Bootstrapper registrando o Serviço e o Controlador que você usará para Injeção de Dependência.

  1. Agora, você conectará o Bootstrapper, que é o arquivo que inicializa o contêiner do Unity e o Resolvedor de Dependências. Para fazer isso, abra Global.asax.cs e adicione o código realçado a seguir no método Application_Start .

    (Snippet de código – laboratório de injeção de dependência ASP.NET – Ex01 – Inicializar o Unity)

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
    
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    
        Bootstrapper.Initialise();
    
        AppConfig.Configure();
    }
    
  2. Abra o arquivo Bootstrapper.cs .

  3. Inclua os seguintes namespaces: MvcMusicStore.Services e MusicStore.Controllers.

    (Snippet de código – laboratório de injeção de dependência ASP.NET – Ex01 – Bootstrapper adicionando namespaces)

    using System.Web.Mvc;
    using Microsoft.Practices.Unity;
    using Unity.Mvc3;
    using MvcMusicStore.Services;
    using MvcMusicStore.Controllers;
    
  4. Substitua o conteúdo do método BuildUnityContainer pelo código a seguir que registra o Store Controller e o Store Service.

    (Snippet de código – laboratório de injeção de dependência ASP.NET – Ex01 – Registrar o controlador e o serviço do repositório)

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
    
        container.RegisterType<IStoreService, StoreService>();
        container.RegisterType<IController, StoreController>("Store");
    
        return container;
    }
    

Tarefa 4 – Executando o aplicativo

Nesta tarefa, você executará o aplicativo para verificar se ele agora pode ser carregado depois de incluir o Unity.

  1. Pressione F5 para executar o aplicativo, o aplicativo agora deve ser carregado sem mostrar nenhuma mensagem de erro.

    Executando o aplicativo com injeção de dependência

    Executando o aplicativo com injeção de dependência

  2. Navegue até /Store. Isso invocará StoreController, que agora é criado usando o Unity.

    MVC Music Store

    MVC Music Store

  3. Feche o navegador.

Nos exercícios a seguir, você aprenderá a estender o escopo de Injeção de Dependência para usá-lo dentro ASP.NET exibições do MVC e filtros de ação.

Exercício 2: Injetando uma exibição

Neste exercício, você aprenderá a usar a Injeção de Dependência em uma exibição com os novos recursos do ASP.NET MVC 4 para integração do Unity. Para fazer isso, você chamará um serviço personalizado dentro do Modo de Exibição de Navegação da Loja, que mostrará uma mensagem e uma imagem abaixo.

Em seguida, você integrará o projeto ao Unity e criará um resolvedor de dependência personalizado para injetar as dependências.

Tarefa 1 – Criando um modo de exibição que consome um serviço

Nesta tarefa, você criará uma exibição que executa uma chamada de serviço para gerar uma nova dependência. O serviço consiste em um serviço de mensagens simples incluído nesta solução.

  1. Abra a solução Begin localizada na pasta Source\Ex02-Injecting View\Begin . Caso contrário, você poderá continuar usando a solução End obtida concluindo o exercício anterior.

    1. Se você abriu a solução Begin fornecida, precisará baixar alguns pacotes NuGet ausentes antes de continuar. Para fazer isso, clique no menu Projeto e selecione Gerenciar Pacotes NuGet.

    2. Na caixa de diálogo Gerenciar Pacotes NuGet , clique em Restaurar para baixar pacotes ausentes.

    3. Por fim, crie a solução clicando em Compilar | Compilar Solução.

      Observação

      Uma das vantagens de usar o NuGet é que você não precisa enviar todas as bibliotecas em seu projeto, reduzindo o tamanho do projeto. Com o NuGet Power Tools, especificando as versões do pacote no arquivo Packages.config, você poderá baixar todas as bibliotecas necessárias na primeira vez que executar o projeto. É por isso que você precisará executar essas etapas depois de abrir uma solução existente neste laboratório.

      Para obter mais informações, consulte este artigo: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages.

  2. Inclua as classes MessageService.cs e IMessageService.cs localizadas na pasta Source \Assets em /Services. Para fazer isso, clique com o botão direito do mouse na pasta Serviços e selecione Adicionar Item Existente. Navegue até o local dos arquivos e inclua-os.

    Adicionando serviço de mensagem e interface de serviço

    Adicionando serviço de mensagem e interface de serviço

    Observação

    A interface IMessageService define duas propriedades implementadas pela classe MessageService . Essas propriedades -Message e ImageUrl- armazenam a mensagem e a URL da imagem a ser exibida.

  3. Crie a pasta /Pages na pasta raiz do projeto e adicione a classe existente MyBasePage.cs de Source\Assets. A página base da qual você herdará tem a seguinte estrutura.

    Pasta Páginas

    namespace MvcMusicStore.Pages
    {
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using Microsoft.Practices.Unity;
        using MvcMusicStore.Models;
        using MvcMusicStore.Services;
    
        public class MyBasePage : System.Web.Mvc.WebViewPage<Genre>
        {
            [Dependency]
            public IMessageService MessageService { get; set; }
    
            public override void 
    
            Execute()
            {
            }
        }
    }
    
  4. Abra a exibição Browse.cshtml na pasta /Views/Store e faça com que ela herde de MyBasePage.cs.

    @inherits MvcMusicStore.Pages.MyBasePage
    @{
         ViewBag.Title = "Browse Albums";
    }
    
  5. No modo de exibição Procurar , adicione uma chamada a MessageService para exibir uma imagem e uma mensagem recuperada pelo serviço. (C#)

    @inherits MvcMusicStore.Pages.MyBasePage    
    @{
        Viewbag.Title = "Browse Albums";
    }
    <div>
        @this.MessageService.Message
        <br />
        <img alt="@this.MessageService.Message" src="@this.MessageService.ImageUrl" />
    </div>
    ...
    

Tarefa 2 – Incluindo um Resolvedor de Dependência Personalizado e um Ativador de Página de Exibição Personalizada

Na tarefa anterior, você injetou uma nova dependência dentro de uma exibição para executar uma chamada de serviço dentro dela. Agora, você resolve essa dependência implementando as interfaces de injeção de dependência do ASP.NET MVC IViewPageActivator e IDependencyResolver. Você incluirá na solução uma implementação de IDependencyResolver que lidará com a recuperação de serviço usando o Unity. Em seguida, você incluirá outra implementação personalizada da interface IViewPageActivator que resolverá a criação dos modos de exibição.

Observação

Desde ASP.NET MVC 3, a implementação da Injeção de Dependência simplificava as interfaces para registrar serviços. IDependencyResolver e IViewPageActivator fazem parte de ASP.NET recursos do MVC 3 para injeção de dependência.

– A interface IDependencyResolver substitui o IMvcServiceLocator anterior. Os implementadores de IDependencyResolver devem retornar uma instância do serviço ou uma coleção de serviços.

public interface IDependencyResolver {
    object GetService(Type serviceType);
    IEnumerable<object> GetServices(Type serviceType);
}

– A interface IViewPageActivator fornece um controle mais refinado sobre como as páginas de exibição são instanciadas por meio de injeção de dependência. As classes que implementam a interface IViewPageActivator podem criar instâncias de exibição usando informações de contexto.

public interface IViewPageActivator {
    object Create(ControllerContext controllerContext, Type type);
}
  1. Crie a pasta /Factories na pasta raiz do projeto.

  2. Inclua CustomViewPageActivator.cs para sua solução de /Sources/Assets/ para a pasta Factories . Para fazer isso, clique com o botão direito do mouse na pasta /Factories , selecione Adicionar | Item existente e, em seguida, selecione CustomViewPageActivator.cs. Essa classe implementa a interface IViewPageActivator para manter o Contêiner do Unity.

    namespace MvcMusicStore.Factories
    {
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.Mvc;
        using Microsoft.Practices.Unity;
    
        public class CustomViewPageActivator : IViewPageActivator
        {
            private IUnityContainer container;
    
            public CustomViewPageActivator(IUnityContainer container)
            {
                this.container = container;
            }
    
            public object Create(ControllerContext controllerContext, Type type)
            {
                return this.container.Resolve(type);
            }
        }
    }
    

    Observação

    CustomViewPageActivator é responsável por gerenciar a criação de uma exibição usando um contêiner do Unity.

  3. Inclua o arquivo UnityDependencyResolver.cs de /Sources/Assets para a pasta /Factories . Para fazer isso, clique com o botão direito do mouse na pasta /Factories , selecione Adicionar | Item existente e, em seguida, selecione UnityDependencyResolver.cs arquivo.

    namespace MvcMusicStore.Factories
    {
         using System;
         using System.Collections.Generic;
         using System.Linq;
         using System.Web;
         using System.Web.Mvc;
         using Microsoft.Practices.Unity;
    
         public class UnityDependencyResolver : IDependencyResolver
         {
              private IUnityContainer container;
    
              private IDependencyResolver resolver;
    
              public UnityDependencyResolver(IUnityContainer container, IDependencyResolver resolver)
              {
                    this.container = container;
                    this.resolver = resolver;
              }
    
              public object GetService(Type serviceType)
              {
                    try
                    {
                         return this.container.Resolve(serviceType);
                    }
                    catch
                    {
                         return this.resolver.GetService(serviceType);
                    }
              }
    
              public IEnumerable<object> GetServices(Type serviceType)
              {
                    try
                    {
                         return this.container.ResolveAll(serviceType);
                    }
                    catch
                    {
                         return this.resolver.GetServices(serviceType);
                    }
              }
         }
    }
    

    Observação

    A classe UnityDependencyResolver é uma DependencyResolver personalizada para Unity. Quando um serviço não pode ser encontrado dentro do contêiner do Unity, o resolvedor base é invocado.

Na tarefa a seguir, ambas as implementações serão registradas para informar ao modelo o local dos serviços e as exibições.

Tarefa 3 – Registrar-se para injeção de dependência dentro do contêiner do Unity

Nesta tarefa, você colocará todas as coisas anteriores juntas para fazer a Injeção de Dependência funcionar.

Até agora, sua solução tem os seguintes elementos:

  • Um Modo de Exibição de Navegação que herda de MyBaseClass e consome MessageService.
  • Uma classe intermediária -MyBaseClass- que tem injeção de dependência declarada para a interface de serviço.
  • Um serviço – MessageService – e sua interface IMessageService.
  • Um resolvedor de dependência personalizado para Unity – UnityDependencyResolver – que lida com a recuperação de serviço.
  • Um ativador de Página de Exibição – CustomViewPageActivator – que cria a página.

Para injetar o Modo de Exibição de Navegação, agora você registrará o resolvedor de dependência personalizado no contêiner do Unity.

  1. Abra o arquivo Bootstrapper.cs .

  2. Registre uma instância de MessageService no contêiner do Unity para inicializar o serviço:

    (Snippet de código – ASP.NET Laboratório de Injeção de Dependência – Ex02 – Registrar Serviço de Mensagem)

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
    
        container.RegisterType<IStoreService, StoreService>();
        container.RegisterType<IController, StoreController>("Store");
    
        container.RegisterInstance<IMessageService>(new MessageService
        {
            Message = "You are welcome to our Web Camps Training Kit!",
            ImageUrl = "/Content/Images/webcamps.png"
        });
        //...
    }
    
  3. Adicione uma referência ao namespace MvcMusicStore.Factories .

    (Snippet de código – laboratório de injeção de dependência ASP.NET – Ex02 – Namespace Factories)

    using System.Web.Mvc; 
    using Microsoft.Practices.Unity; 
    using Unity.Mvc3; 
    using MvcMusicStore.Services; 
    using MvcMusicStore.Controllers; 
    using MvcMusicStore.Factories;
    
  4. Registre CustomViewPageActivator como um ativador de Página de Exibição no contêiner do Unity:

    (Snippet de código – ASP.NET Laboratório de Injeção de Dependência – Ex02 – Registrar CustomViewPageActivator)

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
    
        container.RegisterType<IStoreService, StoreService>();
        container.RegisterType<IController, StoreController>("Store");
    
        container.RegisterInstance<IMessageService>(new MessageService
        {
            Message = "You are welcome to our Web Camps Training Kit!",
            ImageUrl = "/Content/Images/webcamps.png"
        });
    
        container.RegisterType<IViewPageActivator, CustomViewPageActivator>(new InjectionConstructor(container));
    
        return container;
    }
    
  5. Substitua ASP.NET resolvedor de dependência padrão do MVC 4 por uma instância de UnityDependencyResolver. Para fazer isso, substitua o conteúdo do método Initialize pelo seguinte código:

    (Snippet de código – laboratório de injeção de dependência ASP.NET – Ex02 – Atualizar resolvedor de dependência)

    public static void Initialise()
    {
        var container = BuildUnityContainer();
    
        DependencyResolver.SetResolver(new Unity.Mvc3.UnityDependencyResolver(container));
    
        IDependencyResolver resolver = DependencyResolver.Current;
    
        IDependencyResolver newResolver = new Factories.UnityDependencyResolver(container, resolver);
    
        DependencyResolver.SetResolver(newResolver);
    }
    

    Observação

    ASP.NET MVC fornece uma classe de resolvedor de dependência padrão. Para trabalhar com resolvedores de dependência personalizados como aquele que criamos para o Unity, esse resolvedor deve ser substituído.

Tarefa 4 – Executando o aplicativo

Nesta tarefa, você executará o aplicativo para verificar se o Navegador da Loja consome o serviço e mostra a imagem e a mensagem recuperada:

  1. Pressione F5 para executar o aplicativo.

  2. Clique em Rock no Menu Gêneros e veja como o MessageService foi injetado no modo de exibição e carregou a mensagem de boas-vindas e a imagem. Neste exemplo, estamos inserindo para "Rock":

    Repositório de MúsicaS MVC – Repositório de Músicas MVC de Injeção de Exibição

    Repositório de MúsicaS MVC – Injeção de Exibição

  3. Feche o navegador.

Exercício 3: Injetando filtros de ação

No laboratório Hands-On filtros de ação personalizada anteriores, você trabalhou com a personalização e a injeção de filtros. Neste exercício, você aprenderá a injetar filtros com Injeção de Dependência usando o contêiner do Unity. Para fazer isso, você adicionará à solução da Music Store um filtro de ação personalizado que rastreará a atividade do site.

Tarefa 1 – Incluindo o filtro de acompanhamento na solução

Nesta tarefa, você incluirá na Loja de Música um filtro de ação personalizado para rastrear eventos. Como os conceitos de filtro de ação personalizado já são tratados no laboratório anterior "Filtros de Ação Personalizada", você incluirá apenas a classe de filtro da pasta Ativos deste laboratório e, em seguida, criará um Provedor de Filtro para Unity:

  1. Abra a solução Begin localizada na pasta Source\Ex03 - Injecting Action Filter\Begin . Caso contrário, você poderá continuar usando a solução End obtida concluindo o exercício anterior.

    1. Se você abriu a solução Begin fornecida, precisará baixar alguns pacotes NuGet ausentes antes de continuar. Para fazer isso, clique no menu Projeto e selecione Gerenciar Pacotes NuGet.

    2. Na caixa de diálogo Gerenciar Pacotes NuGet , clique em Restaurar para baixar pacotes ausentes.

    3. Por fim, crie a solução clicando em Compilar | Compilar Solução.

      Observação

      Uma das vantagens de usar o NuGet é que você não precisa enviar todas as bibliotecas em seu projeto, reduzindo o tamanho do projeto. Com o NuGet Power Tools, especificando as versões do pacote no arquivo Packages.config, você poderá baixar todas as bibliotecas necessárias na primeira vez que executar o projeto. É por isso que você precisará executar essas etapas depois de abrir uma solução existente neste laboratório.

      Para obter mais informações, consulte este artigo: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages.

  2. Inclua o arquivo TraceActionFilter.cs de /Sources/Assets para a pasta /Filters .

    namespace MvcMusicStore.Filters
    {
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.Mvc;
    
        public class TraceActionFilter : IActionFilter
        {
            public void OnActionExecuted(ActionExecutedContext filterContext)
            {
                filterContext.HttpContext.Trace.Write("OnActionExecuted");
                filterContext.HttpContext.Trace.Write("Action " + filterContext.ActionDescriptor.ActionName);
                filterContext.HttpContext.Trace.Write("Controller " + filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
            }
    
            public void OnActionExecuting(ActionExecutingContext filterContext)
            {
                filterContext.HttpContext.Trace.Write("OnActionExecuting");
                filterContext.HttpContext.Trace.Write("Action " + filterContext.ActionDescriptor.ActionName);
                filterContext.HttpContext.Trace.Write("Controller " + filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
            }
        }
    }
    

    Observação

    Esse filtro de ação personalizado executa ASP.NET rastreamento. Você pode marcar laboratório "ASP.NET filtros de ação local e dinâmica do MVC 4" para obter mais referência.

  3. Adicione a classe vazia FilterProvider.cs ao projeto na pasta /Filters.

  4. Adicione os namespaces System.Web.Mvc e Microsoft.Practices.Unity em FilterProvider.cs.

    (Snippet de código – ASP.NET Laboratório de Injeção de Dependência – Ex03 – Provedor de Filtro adicionando namespaces)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Microsoft.Practices.Unity;
    
    namespace MvcMusicStore.Filters
    {
         public class FilterProvider
         {
         }
    }
    
  5. Faça com que a classe herde da Interface IFilterProvider .

    namespace MvcMusicStore.Filters
    {
        public class FilterProvider : IFilterProvider
        {
        }
    }
    
  6. Adicione uma propriedade IUnityContainer na classe FilterProvider e, em seguida, crie um construtor de classe para atribuir o contêiner.

    (Snippet de código – ASP.NET Laboratório de Injeção de Dependência – Ex03 – Construtor do Provedor de Filtros)

    public class FilterProvider : IFilterProvider
    {
        private IUnityContainer container;
    
        public FilterProvider(IUnityContainer container)
        {
            this.container = container;
        }
    }
    

    Observação

    O construtor de classe do provedor de filtro não está criando um novo objeto no interior. O contêiner é passado como um parâmetro e a dependência é resolvida pelo Unity.

  7. Na classe FilterProvider , implemente o método GetFilters da interface IFilterProvider .

    (Snippet de código – laboratório de injeção de dependência ASP.NET – Ex03 – Filtro provedor GetFilters)

    public class FilterProvider : IFilterProvider
    {
        private IUnityContainer container;
    
        public FilterProvider(IUnityContainer container)
        {
            this.container = container;
        }
    
        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
        {
            foreach (IActionFilter actionFilter in this.container.ResolveAll<IActionFilter>())
            {
                yield return new Filter(actionFilter, FilterScope.First, null);
            }
        }
    }
    

Tarefa 2 – Registrar e habilitar o filtro

Nesta tarefa, você habilitará o acompanhamento do site. Para fazer isso, você registrará o filtro no método BuildUnityContainer bootstrapper.cs para iniciar o rastreamento:

  1. Abra Web.config localizado na raiz do projeto e habilite o rastreamento no grupo System.Web.

    <system.web>
        <trace enabled="true"/>
        <compilation debug="true" targetFramework="4.5">
    
  2. Abra Bootstrapper.cs na raiz do projeto.

  3. Adicione uma referência ao namespace MvcMusicStore.Filters .

    (Snippet de código – laboratório de injeção de dependência ASP.NET – Ex03 – Inicializador adicionando namespaces)

    using System.Web.Mvc;
    using Microsoft.Practices.Unity;
    using Unity.Mvc3;
    using MvcMusicStore.Services;
    using MvcMusicStore.Controllers;
    using MvcMusicStore.Factories;
    using MvcMusicStore.Filters;
    
  4. Selecione o método BuildUnityContainer e registre o filtro no Contêiner do Unity. Você precisará registrar o provedor de filtro, bem como o filtro de ação.

    (Snippet de código – ASP.NET Laboratório de Injeção de Dependência – Ex03 – Registrar FilterProvider e ActionFilter)

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
    
        //...
    
        container.RegisterInstance<IFilterProvider>("FilterProvider", new FilterProvider(container));
        container.RegisterInstance<IActionFilter>("LogActionFilter", new TraceActionFilter());
    
        return container;
    }
    

Tarefa 3 – Executando o aplicativo

Nesta tarefa, você executará o aplicativo e testará se o filtro de ação personalizada está rastreando a atividade:

  1. Pressione F5 para executar o aplicativo.

  2. Clique em Rock no Menu Gêneros. Você pode navegar para mais gêneros, se desejar.

    Music Store

    Loja de Música

  3. Navegue até /Trace.axd para ver a página Rastreamento de Aplicativo e clique em Exibir Detalhes.

    logLog de rastreamento do aplicativo de

    Log de rastreamento do aplicativo

    Rastreamento de Aplicativo – Detalhes da Solicitação

    Rastreamento de aplicativo – Detalhes da solicitação

  4. Feche o navegador.


Resumo

Ao concluir este laboratório de Hands-On, você aprendeu a usar a Injeção de Dependência no ASP.NET MVC 4 integrando o Unity usando um pacote NuGet. Para fazer isso, você usou a Injeção de Dependência dentro de controladores, exibições e filtros de ação.

Os seguintes conceitos foram abordados:

  • ASP.NET recursos de injeção de dependência do MVC 4
  • Integração do Unity usando o Pacote NuGet Unity.Mvc3
  • Injeção de dependência em controladores
  • Injeção de dependência em exibições
  • Injeção de dependência de filtros de ação

Apêndice A: Instalando o Visual Studio Express 2012 para Web

Você pode instalar Microsoft Visual Studio Express 2012 para Web ou outra versão "Express" usando o Microsoft Web Platform Installer. As instruções a seguir orientam você pelas etapas necessárias para instalar o Visual Studio Express 2012 para Web usando Microsoft Web Platform Installer.

  1. Ir para https://go.microsoft.com/?linkid=9810169. Como alternativa, se você já tiver instalado o Web Platform Installer, poderá abri-lo e pesquisar o produto "Visual Studio Express 2012 para Web com o SDK do Windows Azure".

  2. Clique em Instalar Agora. Se você não tiver o Web Platform Installer , será redirecionado para baixá-lo e instalá-lo primeiro.

  3. Depois que o Web Platform Installer estiver aberto, clique em Instalar para iniciar a instalação.

    Instalar Visual Studio Express

    Instalar Visual Studio Express

  4. Leia todas as licenças e termos dos produtos e clique em Aceito para continuar.

    Aceitando os termos de licença

    Aceitando os termos de licença

  5. Aguarde até que o processo de download e instalação seja concluído.

    Progresso da instalação

    Progresso da instalação

  6. Quando a instalação for concluída, clique em Concluir.

    Instalação concluída

    Instalação concluída

  7. Clique em Sair para fechar o Web Platform Installer.

  8. Para abrir Visual Studio Express para Web, vá para a tela Inicial e comece a escrever "VS Express" e clique no bloco DO VS Express para Web.

    Bloco do VS Express para Web

    Bloco do VS Express para Web

Apêndice B: Usando snippets de código

Com snippets de código, você tem todo o código necessário ao seu alcance. O documento de laboratório informará exatamente quando você pode usá-los, conforme mostrado na figura a seguir.

Usando snippets de código do Visual Studio para inserir código em seu projeto

Usando snippets de código do Visual Studio para inserir código em seu projeto

Para adicionar um snippet de código usando o teclado (somente C#)

  1. Coloque o cursor onde você deseja inserir o código.
  2. Comece a digitar o nome do snippet (sem espaços ou hifens).
  3. Observe como o IntelliSense exibe os nomes dos snippets correspondentes.
  4. Selecione o snippet correto (ou continue digitando até que o nome do snippet inteiro seja selecionado).
  5. Pressione a tecla Tab duas vezes para inserir o snippet no local do cursor.

Comece a digitar o nome do snippet

Comece a digitar o nome do snippet

Pressione Tab para selecionar o snippet de código realçado

Pressione Tab para selecionar o snippet realçado

Pressione Tab novamente e o snippet expandirá

Pressione Tab novamente e o snippet se expandirá

Para adicionar um snippet de código usando o mouse (C#, Visual Basic e XML) 1. Clique com o botão direito do mouse no local em que você deseja inserir o snippet de código.

  1. Selecione Inserir Snippet seguido por Meus Snippets de Código.
  2. Escolha o snippet relevante na lista clicando nele.

Clique com o botão direito do mouse onde você deseja inserir o snippet de código e selecione Inserir Snippet

Clique com o botão direito do mouse onde você deseja inserir o snippet de código e selecione Inserir Snippet

Escolha o snippet relevante da lista clicando nele

Escolha o snippet relevante na lista clicando nele