Внедрение зависимостей в ASP.NET MVC 4

Команда веб-лагерей

Скачать комплект для обучения в веб-лагерях

В этом практическом задании предполагается, что у вас есть базовые знания о фильтрах MVC ASP.NET MVC и ASP.NET MVC 4. Если вы ранее не использовали ASP.NET фильтрах MVC 4 , рекомендуем перейти к ASP.NET практических занятий по фильтрам настраиваемых действий MVC .

Примечание

Все примеры кода и фрагменты кода включены в комплект для обучения веб-лагерей, доступный в выпусках Microsoft-Web/WebCampTrainingKit. Проект для этой лаборатории доступен на странице ASP.NET внедрение зависимостей MVC 4.

В парадигме объектно-ориентированного программирования объекты работают вместе в модели совместной работы, где есть участники и потребители. Естественно, эта модель связи создает зависимости между объектами и компонентами, что затрудняет управление при увеличении сложности.

Зависимости классов и сложность модели

Зависимости классов и сложность модели

Вы, вероятно, слышали о шаблоне фабрики и разделении между интерфейсом и реализацией, использующими службы, где клиентские объекты часто отвечают за расположение службы.

Шаблон внедрения зависимостей — это конкретная реализация инверсии элемента управления. Инверсия элемента управления (IoC) означает, что объекты не создают другие объекты, от которых они полагаются для выполнения своей работы. Вместо этого они получают необходимые объекты из внешнего источника (например, xml-файла конфигурации).

Внедрение зависимостей (DI) означает, что это делается без вмешательства объекта, обычно с помощью компонента платформы, который передает параметры конструктора и задает свойства.

Шаблон проектирования внедрения зависимостей (DI)

На высоком уровне целью внедрения зависимостей является то, что классу клиента (например, игроку в гольф) требуется что-то, удовлетворяющее интерфейсу (например , IClub). Он не имеет значения, какой конкретный тип (например , WoodClub, IronClub, WedgeClub или PutterClub), он хочет, чтобы кто-то другой справился с этим (например, хороший caddy). Сопоставитель зависимостей в ASP.NET MVC позволяет зарегистрировать логику зависимостей в другом месте (например, контейнер или пакет клубов).

Схема внедрения зависимостей

Внедрение зависимостей — аналогия с гольфом

Ниже приведены преимущества использования шаблона внедрения зависимостей и инверсии управления.

  • Уменьшает связь между классами
  • Увеличивает повторное выполнение кода.
  • Улучшение поддержки кода
  • Улучшение тестирования приложений

Примечание

Внедрение зависимостей иногда сравнивается с шаблоном проектирования абстрактной фабрики, но между обоими подходами существует небольшая разница. В di имеется платформа, работающая за решение зависимостей путем вызова фабрик и зарегистрированных служб.

Теперь, когда вы понимаете шаблон внедрения зависимостей, вы узнаете, как применить его в ASP.NET MVC 4. Вы начнете использовать внедрение зависимостей в контроллерах , чтобы включить службу доступа к базе данных. Затем вы примените внедрение зависимостей к представлениям , чтобы использовать службу и отображать сведения. Наконец, вы расширите di для ASP.NET фильтров MVC 4, внеся в решение настраиваемый фильтр действий.

В этом практическом задании вы узнаете, как:

  • Интеграция ASP.NET MVC 4 с Unity для внедрения зависимостей с помощью пакетов NuGet
  • Использование внедрения зависимостей внутри контроллера MVC ASP.NET
  • Использование внедрения зависимостей в ASP.NET представлении MVC
  • Использование внедрения зависимостей в фильтре действий MVC ASP.NET

Примечание

Эта лаборатория использует пакет NuGet Unity.Mvc3 для разрешения зависимостей, но можно адаптировать любую платформу внедрения зависимостей для работы с ASP.NET MVC 4.

Предварительные требования

Для выполнения этого задания вам потребуется следующее:

Настройка

Установка фрагментов кода

Для удобства большая часть кода, который вы будете управлять в рамках этой лаборатории, доступна в виде фрагментов кода Visual Studio. Чтобы установить фрагменты кода, выполните файл .\Source\Setup\CodeSnippets.vsi .

Если вы не знакомы с Visual Studio Code фрагменты кода и хотите узнать, как их использовать, обратитесь к приложению из этого документа "Приложение Б. Использование фрагментов кода".


Упражнения

Эта Hands-On Lab состоит из следующих упражнений:

  1. Упражнение 1. Внедрение контроллера
  2. Упражнение 2. Внедрение представления
  3. Упражнение 3. Внедрение фильтров

Примечание

Каждое упражнение сопровождается папкой End , содержащей полученное решение, которое необходимо получить после выполнения упражнений. Это решение можно использовать в качестве руководства, если вам нужна дополнительная помощь в работе с упражнениями.

Предполагаемое время выполнения этого задания: 30 минут.

Упражнение 1. Внедрение контроллера

В этом упражнении вы узнаете, как использовать внедрение зависимостей в ASP.NET контроллерах MVC путем интеграции Unity с помощью пакета NuGet. По этой причине вы будете включать службы в контроллеры MvcMusicStore, чтобы отделить логику от доступа к данным. Службы создадут в конструкторе контроллера новую зависимость, которая будет разрешена с помощью внедрения зависимостей с помощью Unity.

Этот подход показывает, как создавать менее связанные приложения, которые являются более гибкими и проще в обслуживании и тестировании. Вы также узнаете, как интегрировать ASP.NET MVC с Unity.

Сведения о службе StoreManager

Хранилище музыки MVC, предоставляемое в начальном решении, теперь включает в себя службу, которая управляет данными контроллера магазина с именем StoreService. Ниже приведена реализация службы Store. Обратите внимание, что все методы возвращают сущности 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 с самого начала решения теперь использует StoreService. Все ссылки на данные были удалены из StoreController, и теперь можно изменить текущий поставщик доступа к данным, не изменяя метод, который использует StoreService.

Ниже вы увидите, что реализация StoreController имеет зависимость с StoreService в конструкторе класса.

Примечание

Зависимость, представленная в этом упражнении, связана с инверсией управления (IoC).

Конструктор класса StoreController получает параметр типа IStoreService , который необходим для выполнения вызовов служб из класса . Однако StoreController не реализует конструктор по умолчанию (без параметров), который должен иметь любой контроллер для работы с ASP.NET MVC.

Чтобы разрешить зависимость, контроллер должен быть создан абстрактной фабрикой (классом, который возвращает любой объект указанного типа).

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);
        }
    }
}

Примечание

При попытке класса создать StoreController без отправки объекта службы возникнет ошибка, так как конструктор без параметров не объявлен.

Задача 1. Запуск приложения

В этой задаче вы запустите приложение Begin, которое включает службу в контроллер Store, который отделяет доступ к данным от логики приложения.

При запуске приложения вы получите исключение, так как служба контроллера не передается в качестве параметра по умолчанию:

  1. Откройте решение Begin , расположенное в папке Source\Ex01-Injecting Controller\Begin.

    1. Прежде чем продолжить, вам потребуется скачать некоторые отсутствующие пакеты NuGet. Для этого щелкните меню Проект и выберите Управление пакетами NuGet.

    2. В диалоговом окне Управление пакетами NuGet нажмите кнопку Восстановить , чтобы скачать отсутствующие пакеты.

    3. Наконец, выполните сборку решения, щелкнув BuildSolution (Сборка | решения).

      Примечание

      Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакета в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Именно поэтому эти действия необходимо выполнить после открытия существующего решения из этой лаборатории.

  2. Нажмите клавиши CTRL+F5 , чтобы запустить приложение без отладки. Вы получите сообщение об ошибке No parameterless constructor defined for this object (Конструктор без параметров не определен для этого объекта):

    Ошибка при выполнении ASP.NET MVC Begin Application

    Ошибка при запуске ASP.NET начального приложения MVC

  3. Закройте браузер.

На следующих шагах вы будете работать с решением хранилища музыки, чтобы внедрить зависимость, необходимую этому контроллеру.

Задача 2. Включение Unity в решение MvcMusicStore

В этой задаче в решение будет включен пакет NuGet Unity.Mvc3 .

Примечание

Пакет Unity.Mvc3 был разработан для ASP.NET MVC 3, но он полностью совместим с ASP.NET MVC 4.

Unity — это упрощенный расширяемый контейнер внедрения зависимостей с необязательной поддержкой перехвата экземпляров и типов. Это контейнер общего назначения для использования в любом типе приложений .NET. Он предоставляет все общие функции, доступные в механизмах внедрения зависимостей, включая создание объектов, абстрагирование требований путем указания зависимостей во время выполнения и гибкость путем отсрочки конфигурации компонента в контейнере.

  1. Установите пакет NuGet Unity.Mvc3 в проекте MvcMusicStore . Для этого откройте консоль диспетчера пакетов в разделе Просмотр | других окон.

  2. Выполните следующую команду:

    PMC

    Install-Package Unity.Mvc3
    

    Установка пакета NuGet Unity.Mvc3

    Установка пакета NuGet Unity.Mvc3

  3. После установки пакета Unity.Mvc3 изучите файлы и папки, которые он автоматически добавляет, чтобы упростить настройку Unity.

    Установленный пакет Unity.Mvc3

    Установленный пакет Unity.Mvc3

Задача 3. Регистрация Unity в Global.asax.cs Application_Start

В этой задаче вы обновите метод Application_Start , расположенный в файле Global.asax.cs , чтобы вызвать инициализатор начального загрузчика Unity, а затем обновите файл начального загрузчика, регистрирующий службу и контроллер, которые будут использоваться для внедрения зависимостей.

  1. Теперь вы подключите начальный загрузчик, который является файлом, который инициализирует контейнер Unity и сопоставитель зависимостей. Для этого откройте файл Global.asax.cs и добавьте следующий выделенный код в метод Application_Start .

    (Фрагмент кода — ASP.NET лаборатория внедрения зависимостей — Ex01 — инициализация 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. Откройте файл Bootstrapper.cs .

  3. Включите следующие пространства имен: MvcMusicStore.Services и MusicStore.Controllers.

    (Фрагмент кода — ASP.NET лаборатории внедрения зависимостей — Ex01 — добавление пространств имен начального загрузчика)

    using System.Web.Mvc;
    using Microsoft.Practices.Unity;
    using Unity.Mvc3;
    using MvcMusicStore.Services;
    using MvcMusicStore.Controllers;
    
  4. Замените содержимое метода BuildUnityContainer следующим кодом, который регистрирует контроллер Store и службу Store.

    (Фрагмент кода — ASP.NET лаборатории внедрения зависимостей — Ex01 — регистрация контроллера и службы хранилища)

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

Задача 4. Запуск приложения

В этой задаче вы запустите приложение, чтобы убедиться, что его можно загрузить после включения Unity.

  1. Нажмите клавишу F5 , чтобы запустить приложение. Теперь приложение должно загружаться без сообщения об ошибке.

    Запущенное приложение с внедрением зависимостей

    Запуск приложения с внедрением зависимостей

  2. Перейдите в /Store. Это вызовет StoreController, который теперь создается с помощью Unity.

    MVC Music Store

    MVC Music Store

  3. Закройте браузер.

В следующих упражнениях вы узнаете, как расширить область внедрения зависимостей, чтобы использовать его в ASP.NET представлениях И фильтрах действий MVC.

Упражнение 2. Внедрение представления

В этом упражнении вы узнаете, как использовать внедрение зависимостей в представлении с новыми функциями ASP.NET MVC 4 для интеграции Unity. Для этого необходимо вызвать пользовательскую службу в представлении обзора Магазина, где будет отображаться сообщение и изображение ниже.

Затем вы интегрируете проект с Unity и создадите настраиваемый сопоставитель зависимостей для внедрения зависимостей.

Задача 1. Создание представления, использующее службу

В этой задаче вы создадите представление, которое выполняет вызов службы для создания новой зависимости. Служба состоит из простой службы обмена сообщениями, включенной в это решение.

  1. Откройте решение Begin , расположенное в папке Source\Ex02-Injecting View\Begin . В противном случае вы можете продолжить использовать решение End , полученное при выполнении предыдущего упражнения.

    1. Если вы открыли предоставленное решение Begin , вам потребуется скачать некоторые отсутствующие пакеты NuGet, прежде чем продолжить. Для этого щелкните меню Проект и выберите Управление пакетами NuGet.

    2. В диалоговом окне Управление пакетами NuGet нажмите кнопку Восстановить , чтобы скачать отсутствующие пакеты.

    3. Наконец, выполните сборку решения, щелкнув BuildSolution (Сборка | решения).

      Примечание

      Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакета в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Именно поэтому эти действия необходимо выполнить после открытия существующего решения из этой лаборатории.

      Дополнительные сведения см. в этой статье: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages.

  2. Включите классы MessageService.cs и IMessageService.cs , расположенные в папке Source \Assets в папке /Services. Для этого щелкните правой кнопкой мыши папку Службы и выберите Добавить существующий элемент. Перейдите к расположению файлов и включите их.

    Добавление службы сообщений и интерфейса службы

    Добавление службы сообщений и интерфейса службы

    Примечание

    Интерфейс IMessageService определяет два свойства, реализованные классом MessageService . Эти свойства — Message и ImageUrl — хранят сообщение и URL-адрес отображаемого изображения.

  3. Создайте папку /Pages в корневой папке проекта, а затем добавьте существующий класс MyBasePage.cs из source\Assets. Базовая страница, от которого вы будете наследовать, имеет следующую структуру.

    Папка Pages

    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. Откройте представление Browse.cshtml из папки /Views/Store и наследуйте его от Файла MyBasePage.cs.

    @inherits MvcMusicStore.Pages.MyBasePage
    @{
         ViewBag.Title = "Browse Albums";
    }
    
  5. В представлении Обзор добавьте вызов MessageService для отображения изображения и сообщения, полученных службой. C#

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

Задача 2. Включение пользовательского сопоставителя зависимостей и настраиваемого активатора страницы представления

В предыдущей задаче вы ввели новую зависимость в представление для выполнения вызова службы внутри него. Теперь вы решите эту зависимость, реализовав ASP.NET интерфейсы внедрения зависимостей MVC IViewPageActivator и IDependencyResolver. Вы включите в решение реализацию IDependencyResolver , которая будет работать с получением службы с помощью Unity. Затем вы включите еще одну пользовательскую реализацию интерфейса IViewPageActivator , которая будет решать создание представлений.

Примечание

С ASP.NET MVC 3 реализация внедрения зависимостей упростила интерфейсы для регистрации служб. IDependencyResolver и IViewPageActivator являются частью функций ASP.NET MVC 3 для внедрения зависимостей.

— Интерфейс IDependencyResolver заменяет предыдущий IMvcServiceLocator. Реализации IDependencyResolver должны возвращать экземпляр службы или коллекцию служб.

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

— Интерфейс IViewPageActivator обеспечивает более точное управление тем, как создаются экземпляры страниц представления с помощью внедрения зависимостей. Классы, реализующие интерфейс IViewPageActivator , могут создавать экземпляры представлений с использованием контекстных сведений.

public interface IViewPageActivator {
    object Create(ControllerContext controllerContext, Type type);
}
  1. Создайте папку /Factories в корневой папке проекта.

  2. Включите CustomViewPageActivator.cs в решение из папки /Sources/Assets/ в папку Фабрики . Для этого щелкните правой кнопкой мыши папку /Factories и выберите Добавить | Существующий элемент , а затем выберите CustomViewPageActivator.cs. Этот класс реализует интерфейс IViewPageActivator для хранения контейнера 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);
            }
        }
    }
    

    Примечание

    CustomViewPageActivator отвечает за управление созданием представления с помощью контейнера Unity.

  3. Включите файл UnityDependencyResolver.cs из папки /Sources/Assets в папку /Factories . Для этого щелкните правой кнопкой мыши папку /Factories и выберите Добавить | Существующий элемент , а затем выберите файл UnityDependencyResolver.cs .

    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);
                    }
              }
         }
    }
    

    Примечание

    Класс UnityDependencyResolver — это пользовательский класс DependencyResolver для Unity. Если служба не найдена в контейнере Unity, вызовется базовый сопоставитель.

В следующей задаче обе реализации будут зарегистрированы, чтобы сообщить модели о расположении служб и представлениях.

Задача 3. Регистрация для внедрения зависимостей в контейнере Unity

В этой задаче вы объедините все предыдущие элементы, чтобы внедрение зависимостей работало.

На данный момент ваше решение содержит следующие элементы:

  • Представление Обзора , которое наследуется от MyBaseClass и использует MessageService.
  • Промежуточный класс MyBaseClass с объявленным внедрением зависимостей для интерфейса службы.
  • Служба MessageService и ее интерфейс IMessageService.
  • Настраиваемый сопоставитель зависимостей для Unity — UnityDependencyResolver , который занимается получением службы.
  • Активатор страницы просмотра CustomViewPageActivator , который создает страницу.

Чтобы внедрить представление обзора , необходимо зарегистрировать настраиваемый сопоставитель зависимостей в контейнере Unity.

  1. Откройте файл Bootstrapper.cs .

  2. Зарегистрируйте экземпляр MessageService в контейнере Unity для инициализации службы:

    (Фрагмент кода — ASP.NET лаборатории внедрения зависимостей — Ex02 — регистрация службы сообщений)

    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. Добавьте ссылку на пространство имен MvcMusicStore.Factories .

    (Фрагмент кода — ASP.NET лаборатория внедрения зависимостей — Ex02 — пространство имен фабрик)

    using System.Web.Mvc; 
    using Microsoft.Practices.Unity; 
    using Unity.Mvc3; 
    using MvcMusicStore.Services; 
    using MvcMusicStore.Controllers; 
    using MvcMusicStore.Factories;
    
  4. Зарегистрируйте CustomViewPageActivator в качестве активатора страницы просмотра в контейнере Unity:

    (Фрагмент кода — ASP.NET лаборатории внедрения зависимостей — Ex02 — Register 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. Замените ASP.NET сопоставителя зависимостей MVC 4 по умолчанию экземпляром UnityDependencyResolver. Для этого замените содержимое метода Initialize следующим кодом:

    (Фрагмент кода — ASP.NET лаборатория внедрения зависимостей — Ex02 — обновление сопоставителя зависимостей)

    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);
    }
    

    Примечание

    ASP.NET MVC предоставляет класс сопоставителя зависимостей по умолчанию. Чтобы работать с пользовательскими сопоставителями зависимостей, созданными для unity, необходимо заменить этот сопоставитель.

Задача 4. Запуск приложения

В этой задаче вы запустите приложение, чтобы убедиться, что браузер Магазина использует службу и отображает изображение и полученное сообщение:

  1. Нажмите клавишу F5 для запуска приложения.

  2. Щелкните Rock в меню Жанры и посмотрите, как служба MessageService была внедрена в представление и загружена приветственное сообщение и изображение. В этом примере мы введем в "Rock":

    Хранилище музыки MVC — просмотр внедрения

    Хранилище музыки MVC — просмотр внедрения

  3. Закройте браузер.

Упражнение 3. Внедрение фильтров действий

В предыдущем Hands-On лаборатории Настраиваемые фильтры действий вы работали с настройкой и внедрением фильтров. В этом упражнении вы узнаете, как внедрять фильтры с помощью внедрения зависимостей с помощью контейнера Unity. Для этого вы добавите в решение "Магазин музыки" настраиваемый фильтр действий, который будет отслеживать активность сайта.

Задача 1. Включение фильтра отслеживания в решение

В этой задаче вы добавите в хранилище музыки настраиваемый фильтр действий для трассировки событий. Так как основные понятия настраиваемого фильтра действий уже рассматриваются в предыдущей лаборатории "Настраиваемые фильтры действий", вы просто включите класс фильтра из папки Assets этой лаборатории, а затем создадите поставщика фильтров для Unity:

  1. Откройте решение Begin , расположенное в папке Source\Ex03 - Injecting Action Filter\Begin . В противном случае вы можете продолжить использовать решение End , полученное при выполнении предыдущего упражнения.

    1. Если вы открыли предоставленное решение Begin , вам потребуется скачать некоторые отсутствующие пакеты NuGet, прежде чем продолжить. Для этого щелкните меню Проект и выберите Управление пакетами NuGet.

    2. В диалоговом окне Управление пакетами NuGet нажмите кнопку Восстановить , чтобы скачать отсутствующие пакеты.

    3. Наконец, выполните сборку решения, щелкнув BuildSolution (Сборка | решения).

      Примечание

      Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакета в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Именно поэтому эти действия необходимо выполнить после открытия существующего решения из этой лаборатории.

      Дополнительные сведения см. в этой статье: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages.

  2. Включите файл TraceActionFilter.cs из /Sources/Assets в папку /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);
            }
        }
    }
    

    Примечание

    Этот настраиваемый фильтр действий выполняет трассировку ASP.NET. Вы можете проверка лабораторию "локальные и динамические фильтры MVC 4 ASP.NET" для получения дополнительной справки.

  3. Добавьте пустой класс FilterProvider.cs в проект в папке /Filters.

  4. Добавьте пространства имен System.Web.Mvc и Microsoft.Practices.Unity в файл FilterProvider.cs.

    (Фрагмент кода — ASP.NET лаборатории внедрения зависимостей — Ex03 — добавление пространств имен поставщиком фильтра)

    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. Сделайте класс наследуется от интерфейса IFilterProvider .

    namespace MvcMusicStore.Filters
    {
        public class FilterProvider : IFilterProvider
        {
        }
    }
    
  6. Добавьте свойство IUnityContainer в класс FilterProvider , а затем создайте конструктор класса для назначения контейнера.

    (Фрагмент кода — ASP.NET лаборатории внедрения зависимостей — Ex03 — конструктор поставщика фильтров)

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

    Примечание

    Конструктор класса поставщика фильтра не создает новый объект внутри. Контейнер передается в качестве параметра, а зависимость решается Unity.

  7. В классе FilterProvider реализуйте метод GetFilters из интерфейса IFilterProvider .

    (Фрагмент кода — ASP.NET лаборатории внедрения зависимостей — Ex03 — поставщик фильтров 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);
            }
        }
    }
    

Задача 2. Регистрация и включение фильтра

В этой задаче вы включите отслеживание сайтов. Для этого необходимо зарегистрировать фильтр в методе Bootstrapper.cs BuildUnityContainer , чтобы начать трассировку:

  1. Откройте Web.config в корневом каталоге проекта и включите отслеживание трассировки в группе System.Web.

    <system.web>
        <trace enabled="true"/>
        <compilation debug="true" targetFramework="4.5">
    
  2. Откройте Файл Bootstrapper.cs в корневом каталоге проекта.

  3. Добавьте ссылку на пространство имен MvcMusicStore.Filters .

    (Фрагмент кода — ASP.NET лаборатории внедрения зависимостей — Ex03 — добавление пространств имен начального загрузчика)

    using System.Web.Mvc;
    using Microsoft.Practices.Unity;
    using Unity.Mvc3;
    using MvcMusicStore.Services;
    using MvcMusicStore.Controllers;
    using MvcMusicStore.Factories;
    using MvcMusicStore.Filters;
    
  4. Выберите метод BuildUnityContainer и зарегистрируйте фильтр в контейнере Unity. Вам потребуется зарегистрировать поставщик фильтра, а также фильтр действий.

    (Фрагмент кода — лаборатория внедрения зависимостей ASP.NET — Ex03 — регистрация FilterProvider и ActionFilter)

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

Задача 3. Запуск приложения

В этой задаче вы запустите приложение и убедитесь, что настраиваемый фильтр действий отслеживает действие:

  1. Нажмите клавишу F5 для запуска приложения.

  2. Щелкните Рок в меню Жанры. При желании вы можете перейти к дополнительным жанрам.

    Music Store

    Приложение Music Store

  3. Перейдите по ссылке /Trace.axd , чтобы просмотреть страницу Трассировка приложения, а затем щелкните Просмотреть сведения.

    Журнал трассировки приложений Журнал трассировки приложений

    Журнал трассировки приложений

    Трассировка приложения — сведения о запросе

    Трассировка приложения — сведения о запросе

  4. Закройте браузер.


Сводка

Пройдя эту Hands-On lab, вы узнали, как использовать внедрение зависимостей в ASP.NET MVC 4 путем интеграции Unity с помощью пакета NuGet. Для этого вы использовали внедрение зависимостей внутри контроллеров, представлений и фильтров действий.

Были рассмотрены следующие понятия:

  • Функции внедрения зависимостей ASP.NET MVC 4
  • Интеграция Unity с помощью пакета NuGet Unity.Mvc3
  • Внедрение зависимостей в контроллерах
  • Внедрение зависимостей в представлениях
  • Внедрение зависимостей для фильтров действий

Приложение А. Установка Visual Studio Express 2012 для Web

Вы можете установить Microsoft Visual Studio Express 2012 для Web или другой версии Express с помощью установщик веб-платформы Майкрософт. Ниже приведены инструкции по установке Visual Studio Express 2012 for Web с помощью установщик веб-платформы Майкрософт.

  1. Перейдите к https://go.microsoft.com/?linkid=9810169. Кроме того, если у вас уже установлен установщик веб-платформы, вы можете открыть его и найти продукт "Visual Studio Express 2012 для веб-приложений с пакетом SDK Для Windows Azure".

  2. Щелкните Установить сейчас. Если у вас нет установщика веб-платформы , вы будете перенаправлены на скачивание и установку.

  3. После открытия установщика веб-платформы нажмите кнопку Установить , чтобы начать установку.

    Установка Visual Studio Express

    Установка Visual Studio Express

  4. Прочтите все лицензии и условия продуктов и нажмите кнопку Принимаю , чтобы продолжить.

    Принятие условий лицензии

    Принятие условий лицензии

  5. Дождитесь завершения процесса скачивания и установки.

    Ход установки

    Ход установки

  6. После завершения установки нажмите кнопку Готово.

    Установка завершена

    Установка завершена

  7. Нажмите кнопку Выйти , чтобы закрыть установщик веб-платформы.

  8. Чтобы открыть Visual Studio Express для Интернета, перейдите на начальный экран и начните писать "VS Express", а затем щелкните плитку VS Express для Web.

    Плитка VS Express для Web

    Плитка VS Express для Web

Приложение Б. Использование фрагментов кода

С помощью фрагментов кода у вас есть весь необходимый код под рукой. В лабораторном документе будет указано, когда их можно использовать, как показано на следующем рисунке.

Использование фрагментов кода Visual Studio для вставки кода в проект

Вставка кода в проект с помощью фрагментов кода Visual Studio

Добавление фрагмента кода с помощью клавиатуры (только C#)

  1. Поместите курсор туда, куда вы хотите вставить код.
  2. Начните вводить имя фрагмента кода (без пробелов или дефисов).
  3. Посмотрите, как IntelliSense отображает имена соответствующих фрагментов.
  4. Выберите правильный фрагмент (или продолжайте вводить, пока не будет выбрано имя всего фрагмента).
  5. Дважды нажмите клавишу TAB, чтобы вставить фрагмент в расположение курсора.

Начало ввода имени фрагмента кода

Начало ввода имени фрагмента кода

Нажмите клавишу TAB, чтобы выбрать выделенный фрагмент

Нажмите клавишу TAB, чтобы выбрать выделенный фрагмент.

Нажмите клавишу TAB еще раз, и фрагмент кода снова развернется.

Нажмите клавишу TAB еще раз, и фрагмент кода развернется.

Добавление фрагмента кода с помощью мыши (C#, Visual Basic и XML) 1. Щелкните правой кнопкой мыши в место, куда нужно вставить фрагмент кода.

  1. Выберите Вставить фрагмент кода, а затем фрагменты кода.
  2. Выберите соответствующий фрагмент из списка, щелкнув его.

Щелкните правой кнопкой мыши в место, где нужно вставить фрагмент кода, и выберите Вставить фрагмент.

Щелкните правой кнопкой мыши в место, где нужно вставить фрагмент кода, и выберите Вставить фрагмент кода.

Выберите соответствующий фрагмент из списка, щелкнув его.

Выберите соответствующий фрагмент из списка, щелкнув его.