Конфигурирование UnityContainer в xml-файле в проектах ASP.NET Core

Многие из нас пользуются готовыми DI-контейнерами. В этой небольшой статье пойдет речь о настройке контейнера внедрения зависимостей Unity через xml-конфигурацию в проектах ASP.Net Core. Это позволит нам получать реализации интерфейсов через конструкторы контроллеров. Преимущество настройки через xml перед настройкой непосредственно в коде приложения в том, что она позволяет менять схему зависимостей без перекомпиляции.


Алгоритм первоначальной настройки


Итак, опишем шаги, которые приведут нас к заветной цели.


  1. В первую очередь создадим тестовый проект ASP.Net Core. Назовем его TestWebAplication.


  1. Добавим библиотеки с интерфейсом (Interfaces) и реализацией (Implementations)


В первой создадим для примера интерфейс InterfaceN с одним методом GetStringMsg(), а во второй класс ImplementationN, который реализует интерфейс, вернув строку "Hello, world!". В зависимости проекта TestWebAplication добавим обе эти библиотеки.


  1. Далее добавляем в проект TestWebApplication следующие Nuget-пакеты (в скобках указаны версии, на которых проверялась работоспособность) :


    • Unity (5.8.6)
    • Unity.Configuration (5.2.3)
    • Unity.Microsoft.DependencyInjection (2.0.10)

  2. Добавляем в проект TestWebApplication новый файл App.Config со следующим содержимым:



    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <configSections>
            <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration" />
        </configSections>
        <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
            <container>
                <register
                  type="Interfaces.InterfaceN, Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
                  mapTo="Implementations.ImplementationN, Implementations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
                </register>
            </container>
        </unity>
    </configuration>

Здесь, как видим, задается соответствие интерфейса и реализации.


  1. Изменяем файл Program.cs

...
using Unity.Microsoft.DependencyInjection;
...
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseUnityServiceProvider()
                .UseStartup<Startup>();

Обратите внимание, что были добавлены новый namespace и вызван метод UseUnityServiceProvider() внутри метода CreateWebHostBuilder.


  1. Изменяем файл Startup.cs

...
using Unity;
using Microsoft.Practices.Unity.Configuration;
...
public class Startup
{
     ...
     // Configure Unity container
     public void ConfigureContainer(IUnityContainer container)
     {
         container.LoadConfiguration();
     }
     ...
}

Обратите внимание, что были добавлены два namespace'а и метод ConfigureContainer() для класса Startup.


На этом всё, настройка завершена. Посмотрим как это использовать в контроллере.


Пример использования


    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        InterfaceN _impl;

        public ValuesController(InterfaceN impl)
        {
            _impl = impl;
        }

        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { _impl.GetStringMsg() };
        }
    }

Запускаем, проверяем — работает!



Всем спасибо за внимание, надеюсь эта информация будет кому-нибудь полезна.

Tags:
.net core,unitycontainer,dependency injection

Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.