Готовим ASP.NET5, выпуск №3 — внедрение зависимостей по-новому

Мы продолжаем нашу колонку по теме ASP.NET5 публикацией от Виктора Коцюбана (Gbdrm) — Technical Leader из SoftServe. В этой статье Виктор поделится с вами подробностями нового встроенного функционала внедрений зависимостей в ASP.NET5. Предыдущие статьи из колонки всегда можно прочитать по ссылке #aspnetcolumn — Владимир Юнев

Внедрение зависимости — одна из самых популярных и используемых форм инверсии управления, важного принципа ООП, что позволяет уменьшить сцепление (coupling) — взаимозависимость, взаимосвязанность модулей.

1838120a4ecc4594b644205992b0ee28.png

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

В ASP.NET 5 встроена возможность внедрения зависимости. Что она позволяет и чем выделяется среди других таких подходов рассмотрим ниже. А также попробуем использовать ее на практике.
ASP.NET 5 находится в бета версии и все что здесь описано может изменится до финального релиза. Например, не так давно были серьезные изменения в возможностях внедрения в свойства. Но основная концепция и главные направления этого нововведения уже понятны.

Основы и регистрация сервисов


Большинство зависимостей, что нужны для представлений, контроллеров и т.д. реализованы как сервисы, потому сервис — это минимальная единица которой управляет DI контейнер. Ключевые возможности минималистического контейнера ASP.NET 5 вынесены в интерфейс IServiceProvider. Единственный метод этого интерфейса — object GetService (Type serviceType).

Есть 4 типа инициализации сервисов (4 типа области видимости), которые поддерживаются контейнером:

  1. Instance — возвращается конкретный объект, за создание которого отвечаете вы сами.
  2. Transient — каждый раз возвращается новый объект.
  3. Singleton — всегда возвращается один и тот же объект.
  4. Scoped — эквивалентен сиглтону, но в данной области (например, в области запроса).


Регистрируются сервисы на старте приложения, в классе Startup, метод ConfigureServices (IServiceCollection services), при чем коллекция ServiceCollection так же имеет методы для добавления сервиса с соответствующей областью видимости (Рис. 1).

3da3246d181942f9959a0997921ae83b.png


Рис. 1. — Диаграмма классов

Пример использования extension-методов коллекции ServiceCollection:

public virtual void ConfigureServices(IServiceCollection services)
{
    var settings = new Settings();
    services.AddInstance(settings);

    services.AddScoped();

    services.AddSingleton();
}


После регистрации сервисы доступны во всех классах, что были вызваны через DI, а также доступных в представлениях.

Внедряем сервисы в контроллер


С внедрением в контроллеры все очень просто — оно происходит через конструктор контроллера.

public class HomeController : Controller
{
    private readonly IApplicationEnvironment _appEnvironment;
    private readonly IProductService _productService;
 
    public HomeController(IProductService productService, 
                          IApplicationEnvironment appEnvironment)
    {
        _appEnvironment = appEnvironment;
        _productService = productService;
    }
 
    // ...
}


И больше ничего делать не нужно. Зарегистрированные сервисы доступны как параметры конструктора.
Если мы используем EntityFramework в нашем приложении, то одна их первых зависимостей, о которых мы задумаемся для использования DI — это DbContext. Это позволит нам написать менее завязанный на DbContext код, легче тестировать такой функционал и т.д.

Пример:
github.com/gbdrm/aspnet5/blob/master/src/aspnet5/Controllers/HomeController.cs#L12-L17

Внедрение в представления


Так же существует интересная возможность использования зарегистрированных сервисов в представлениях (*.cshtml).

@model SomeViewModel
@inject SomeContext SomeContext

@SomeContext.PageTitle


Директива @inject говорит движку представлений, что мы хотим использовать сервис SomeContext. И в самом представлении уже можно использовать этот сервис, в данном случае — свойство PageTitle.

Кроме использования сервисов в представлениях еще одно интересное нововведение — это типизированные настройки. Кроме регистрации сервисов есть возможность «зарегистрировать» часть конфигурации, перед этим приведя эту конфигурацию к определенному типу и сделать это можно всего в несколько строк кода.
Пример внедрения типизированной конфигурации в представлении:
github.com/gbdrm/aspnet5/commit/88dc1e708f89edfd30a55ae90265cde9074ae312

Внедрение в свойства и куда пропал [Activate]


Раньше с помощью атрибута [Activate] можно было вытащить соответствующий сервис для свойства. Но разработчиками было принято решение отказаться от этого. Главными причинами для этого послужили проблемы с совместимостью с другими библиотеками для внедрения зависимостей, а также усложнение отладки. Некоторое время проходили дискуссии по этому поводу, много деталей можно прочитать здесь: github.com/aspnet/Mvc/issues/2151, github.com/aspnet/Announcements/issues/28

Но все же возможность внедрения зависимостей через свойства осталась — с помощью атрибута [FromServices].

Давайте создадим тестовый класс, добавим его в контейнер и попробуем внедрить в свойство контроллера.
github.com/gbdrm/aspnet5/commit/3d09ef0c5b6d079884337a6e044262659a4f6250

Заключение


Внедрение зависимостей на уровне фреймворка — это отличный механизм для унификации работы с зависимостями. Реализация в ASP.NET 5 прозрачна и понятна, а конфигурация очень легкая. Несмотря на то, что пока реализация находится в бета-версии, большинство функционала уже стабильно и готово к полноценной разработке. Все исходники контейнера доступны на GitHub — github.com/aspnet/DependencyInjection. Работа идет до сих пор, можно ознакомится не только с функциональностью, но и посмотреть, как создают часть платформы. Если вам интересно узнать больше по теме dependency injection в asp.net 5, есть отличная статья (на английском языке): www.emadashi.com/2015/06/dependency-injection-in-asp-net-5-one-step-deeper.

aspnetcolumngithubСовет! А также, если вам интересна тема ASP.NET5, можно посмотреть примеры, попробовать дописать что-то самому или написать запрос на реализацию какого-либо функционала в проекте с примерами: github.com/gbdrm/aspnet5


Свежие новости


Как вы уже знаете выпущена Visual Studio 2015 с ASP.NET5 Beta5. Подробности о том, что именно включено в релиз Visual Studio можно почитать в этом блоге.

Выпущено обновление ASP.NET5 Beta6 с множеством изменений, улучшений и исправлений ошибок. Подробности обновления можно найти в этом блоге. Вы можете загрузить обновление по этой ссылке.

Опубликованы планы по выпуску релизов платформы в течение ближайших месяцев до выпуска финальной версии ASP.NET5. Согласно им нас ждут версии Beta7 и Beta8, после чего в ноябре мы получим первую версию, готовую к продакшну (RC1), финальная же версия выйдет в первом квартале 2016 года. Подробности каждой версии можно найти по ссылке.

Опубликованы доклады конференции DevCon 2015, в том числе по веб-разработке и теме ASP.NET.

Полезные ссылки


Самая свежая документация по ASP.NET5 расположена по адресу http://docs.asp.net/en/latest/.

Приглашаем вас подключаться к живым трансляциям периодического шоу ASP.NET 5 Community Standup, где разработчики из команды Microsoft делятся последними новостями о платформе. Записи доступны по этой ссылке.

Познакомьтесь с новой статьей о разработке ASP.NET-приложений в Visual Studio Code от Эрика Рейтана, в которой подробно изложены интересные аспекты работы с веб-проектами в VS Code.

Изучите основы ASP.NET5 с новым бесплатным курсом виртуальной академии Microsoft.

Авторам


Друзья, если вам интересно поддержать колонку своим собственным материалом, то прошу написать мне на vyunev@microsoft.com для того чтобы обсудить все детали. Мы разыскиваем авторов, которые могут интересно рассказать про ASP.NET и другие темы.

ffa3f75408e443ab91019bd1a5db699b.png

Об авторе


Коцюбан Виктор
Technical Leader в SoftServe
Gbdrm

.NET Разработчик с более чем 8 годами опыта. Специалист в области Enterprise веб проектов. Последние 4 года занимает должность технического лидера.

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

© Habrahabr.ru