Compartilhar via


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

Por Equipe Web Camps

Baixe o kit de treinamento Web Camps

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

Observação

Todo o código de exemplo e snippets estão incluídos no Kit de Treinamento de Web Camps, disponível em Versões 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 da Programação Orientada a Objetos , os objetos trabalham juntos em um modelo de colaboração onde 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 Factory Pattern e a separação entre a interface e a implementação usando serviços, onde os objetos do cliente geralmente são responsáveis pela localização do serviço.

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

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

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

Em um alto nível, o objetivo da Injeção de Dependência é que uma classe de cliente (por exemplo , o jogador de golfe) precise de algo que satisfaça uma interface (por exemplo, IClub). Não importa qual seja o tipo de concreto (por exemplo , WoodClub, IronClub, WedgeClub ou PutterClub), ele quer que outra pessoa cuide disso (por exemplo, um bom caddie). O Resolvedor de Dependência no MVC ASP.NET pode permitir que você registre sua lógica de dependência em outro lugar (por exemplo, um contêiner ou um saco de clubes).

Diagrama de injeção de dependência

Injeção de dependência - analogia do 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 do código
  • Melhora o teste de aplicativos

Observação

A injeção de dependência às vezes é comparada com o padrão de design de fábrica abstrato, mas há uma pequena diferença entre as duas abordagens. A DI tem um Framework trabalhando por trá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á ao longo deste 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 às Exibições 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 uma exibição do MVC do ASP.NET
  • Usar injeção de dependência dentro de um filtro de ação MVC ASP.NET

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:

Instalação

Instalando trechos de código

Por conveniência, grande parte do código que você gerenciará ao longo deste laboratório está disponível como trechos 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 Código do Visual Studio e quiser aprender a usá-los, consulte o apêndice deste documento "Apêndice B: Usando Snippets de Código".


Exercícios

Este Laboratório Prático é 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 contendo a solução resultante que você deve obter após concluir os exercícios. Você pode usar esta 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 a 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 MVC Music Store fornecido na solução inicial agora inclui um serviço que gerencia os dados do Controlador de Armazenamento chamado StoreService. Abaixo, você encontrará a implementação do Serviço de Loja. Observe que todos os métodos retornam entidades Model.

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 inicial agora consome StoreService. Todas as referências de dados foram removidas de 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 para trabalhar com ASP.NET MVC.

Para resolver a dependência, o controlador deve 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 de Armazenamento que separa o acesso a 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 | 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ê terá que executar essas etapas depois de abrir uma solução existente neste 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 aplicativo MVC Begin

    Erro ao executar ASP.NET aplicativo MVC Begin

  3. Feche o navegador.

Nas etapas a seguir, você trabalhará na solução 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 na 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 instância e tipo. É 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 objetos, abstração de requisitos especificando dependências em tempo de execução 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 estiver instalado, explore os arquivos e pastas que ele adiciona automaticamente para simplificar a configuração do Unity.

    Pacote Unity.Mvc3 instalado

    Pacote Unity.Mvc3 instalado

Tarefa 3 – Registrando o Unity no Global.asax.cs Application_Start

Nesta tarefa, você atualizará o método Application_Start localizado em Global.asax.cs para chamar o inicializador do Unity Bootstrapper 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 seguinte código realçado no método Application_Start .

    (Snippet de código – ASP.NET Laboratório de Injeção de Dependência – 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 Bootstrapper.cs arquivo.

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

    (Snippet de código - ASP.NET Laboratório de Injeção de Dependência - 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 Controlador de Armazenamento e o Serviço de Armazenamento.

    (Snippet de código – ASP.NET Laboratório de Injeção de Dependência – Ex01 – Registrar Controlador e Serviço de Armazenamento)

    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 após a inclusão do 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.

    Loja de música MVC

    Loja de música MVC

  3. Feche o navegador.

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

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 da Visualizaçã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ências personalizado para injetar as dependências.

Tarefa 1 – Criando uma 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ê pode continuar usando a solução final 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ê terá que 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 MyBasePage.cs de classe existente 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 da 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 recuperadas 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ê resolverá essa dependência implementando as interfaces de Injeção de Dependência do MVC ASP.NET 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 das exibições.

Observação

Desde ASP.NET MVC 3, a implementação para Injeção de Dependência simplificou 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 da 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 à sua solução da pasta /Sources/Assets/ para Factories. Para fazer isso, clique com o botão direito do mouse na pasta /Factories , selecione Adicionar | Item existente e 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 UnityDependencyResolver.cs arquivo 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 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 é um DependencyResolver personalizado 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 permitir que o modelo saiba a localização dos serviços e as exibições.

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

Nesta tarefa, você reunirá todas as coisas anteriores 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 Bootstrapper.cs arquivo.

  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 Mensagens)

    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 - ASP.NET Laboratório de Injeção de Dependência - Ex02 - Namespace de Fábricas)

    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 - ASP.NET Laboratório de Injeção de Dependência - 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 o que criamos para o Unity, esse resolvedor precisa 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 recuperadas:

  1. Pressione F5 para executar o aplicativo.

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

    MVC Music Store - Injeção de Visualização

    MVC Music Store - Injeção de Visualização

  3. Feche o navegador.

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

No laboratório prático anterior, Filtros de ação personalizada, você trabalhou com personalização e 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 Music Store um filtro de ação personalizado que rastreará a atividade do site.

Tarefa 1 – Incluindo o filtro de rastreamento 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 personalizada já são tratados nos "Filtros de Ação Personalizada" do laboratório anterior, você apenas incluirá a classe de filtro da pasta Assets 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ê pode continuar usando a solução final 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ê terá que 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 TraceActionFilter.cs arquivo 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 verificar o laboratório "ASP.NET MVC 4 local e filtros de ação dinâmica" para obter mais referências.

  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 a classe herdar da interface IFilterProvider .

    namespace MvcMusicStore.Filters
    {
        public class FilterProvider : IFilterProvider
        {
        }
    }
    
  6. Adicione uma propriedade IUnityContainer na classe FilterProvider e 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 Filtro)

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

    Observação

    O construtor da classe do provedor de filtro não está criando um novo objeto dentro. 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 – ASP.NET Laboratório de Injeção de Dependência – Ex03 – Provedor de Filtro 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 – Registrando e habilitando o filtro

Nesta tarefa, você habilitará o rastreamento do site. Para fazer isso, você registrará o filtro em Bootstrapper.cs método BuildUnityContainer 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 - ASP.NET Laboratório de Injeção de Dependência - ex03 - Bootstrapper 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ê terá que 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 quiser.

    Loja de Música

    Loja de Música

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

    Log de rastreamento de aplicativos

    Log de rastreamento de aplicativos

    Rastreamento de aplicativos - Detalhes da solicitação

    Rastreamento de aplicativos - Detalhes da solicitação

  4. Feche o navegador.


Resumo

Ao concluir este laboratório prático, você aprendeu a usar a injeção de dependência no MVC 4 ASP.NET integrando o Unity usando um pacote NuGet. Para conseguir isso, você usou a Injeção de Dependência dentro de controladores, visualizações e filtros de ação.

Foram abordados os seguintes conceitos:

  • 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 o 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 o Microsoft Web Platform Installer.

  1. Vá para /iis/extensions/introduction-to-iis-express/iis-express-overview?linkid=9810169. Como alternativa, se você já instalou o Web Platform Installer, poderá abri-lo e pesquisar o produto "Visual Studio Express 2012 for Web with Windows Azure SDK".

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

  3. Quando o Web Platform Installer estiver aberto, clique em Instalar para iniciar a configuração.

    Instalar o Visual Studio Express

    Instalar o Visual Studio Express

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

    Aceitando os termos da licença

    Aceitando os termos da licença

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

    Andamento 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 o Visual Studio Express para Web, vá para a tela Iniciar e comece a escrever "VS Express" e clique no bloco VS Express para Web .

    Bloco do VS Express para Web

    Bloco do VS Express para Web

Apêndice B: Usando trechos de código

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

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

Usando trechos 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 deseja inserir o código.
  2. Comece a digitar o nome do snippet (sem espaços ou hífens).
  3. Veja 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 destacado

Pressione Tab para selecionar o snippet destacado

Pressione Tab novamente e o snippet será expandido

Pressione Tab novamente e o snippet será expandido

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

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

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

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

Escolha o snippet relevante da lista, clicando nele

Escolha o snippet relevante da lista, clicando nele