Как разрешить зависимости в ASP.NET Core

автор vadim


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

Внедрение зависимостей — это первоклассная функция в ASP.NET Core. Встроенный поставщик внедрения зависимостей в ASP.NET Core не такой многофункциональный, как контейнеры IoC (инверсия управления), такие как StructureMap и Ninject, но он быстрый, простой в настройке и простой в использовании. В ASP.NET Core можно внедрить как службы платформы, так и службы приложений.

В этой статье рассказывается о различных способах разрешения зависимостей в ASP.NET Core.

Для работы с примерами кода, представленными в этой статье, в вашей системе должна быть установлена ​​Visual Studio 2022. Если у вас еще нет копии, вы можете скачать Visual Studio 2022 здесь.

Создайте проект ASP.NET Core в Visual Studio 2022.

Прежде всего давайте создадим проект ASP.NET Core в Visual Studio 2022. Выполнение этих шагов позволит создать новый проект ASP.NET Core Web API 6 в Visual Studio 2022:

  1. Запустите интегрированную среду разработки Visual Studio 2022.
  2. Нажмите «Создать новый проект».
  3. В окне «Создать новый проект» выберите «ASP.NET Core Web API» из списка отображаемых шаблонов.
  4. Нажмите “Далее.
  5. В окне «Настроить новый проект» укажите имя и местоположение нового проекта.
  6. При желании установите флажок «Поместить решение и проект в один каталог», в зависимости от ваших предпочтений.
  7. Нажмите “Далее.
  8. В показанном ниже окне «Дополнительная информация» выберите .NET 6.0 в качестве целевой платформы из раскрывающегося списка вверху. В поле «Тип аутентификации» оставьте значение «Нет» (по умолчанию).
  9. Убедитесь, что флажки «Включить Docker», «Настроить HTTPS» и «Включить поддержку Open API» сняты, поскольку мы не будем здесь использовать ни одну из этих функций. При желании вы также можете снять флажок «Использовать контроллеры (снимите флажок, чтобы использовать минимальные API)», поскольку мы будем создавать собственный контроллер.
  10. Нажмите Создать.

В результате будет создан новый проект веб-API ASP.NET Core 6 в Visual Studio 2022. Мы будем использовать этот проект для иллюстрации разрешения зависимостей в последующих разделах этой статьи.

Разрешение зависимостей с помощью внедрения конструктора

Теперь создайте следующий интерфейс:

    public interface ICustomFileLogger
    {
        public string Text { get; set; }
        public void Log(string message);
    }

Для простоты это минимальное представление. Класс CustomFileLogger реализует интерфейс ICustomFileLogger, как показано в приведенном ниже фрагменте кода.

public class CustomFileLogger : ICustomFileLogger
{
   public string Text { get; set; }
   public void Log(string message)
   {
      //Write your own implementation here
   }
}

Вы можете зарегистрировать экземпляр типа ICustomFileLogger в качестве службы с заданной областью в методе ConfigurationServices, если вы используете ASP.NET 5, или в файле Program.cs, если вы используете ASP.NET 6.

services.AddScoped<ICustomFileLogger, CustomFileLogger>();

Затем создайте контроллер API с именем DefaultController и введите следующий код:

    [Route("api/[controller]")]
    [ApiController]
    public class DefaultController : ControllerBase
    {
        private ICustomFileLogger _logger;
        public DefaultController(ICustomFileLogger logger)
        {
            _logger = logger;
            if(string.IsNullOrEmpty(_logger.Text))
                _logger.Text = DateTime.UtcNow.ToString();
        }
        [HttpGet]
        public string Get()
        {
            return "Hello World!";
        }
    }

Обратите внимание, как здесь использовалось внедрение конструктора. Конструктор класса DefaultController принимает в качестве параметра экземпляр типа ICustomFileLogger.

Разрешение зависимостей с помощью внедрения метода действия

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

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

[HttpPost("Log")]
public IActionResult Log([FromServices] ICustomFileLogger customFileLogger)
{
   //Write your code here
    return Ok();
}

Часто вам может потребоваться внедрить в контроллер множество различных сервисов. Если вы используете внедрение конструктора, вам придется указать в конструкторе несколько параметров. Лучшим решением этой проблемы является использование IServiceProvider.

Разрешение зависимостей с помощью IServiceProvider

Вы можете использовать интерфейс IServiceCollection для создания контейнера внедрения зависимостей. После создания контейнера экземпляр IServiceCollection объединяется в экземпляр IServiceProvider. Вы можете использовать этот экземпляр для разрешения служб.

Вы можете внедрить экземпляр типа IServiceProvider в любой метод класса. Вы также можете воспользоваться свойством ApplicationServices интерфейса IApplicationBuilder и свойством RequestServices класса HttpContext для получения экземпляра IServiceProvider.

Следующий фрагмент кода показывает, как можно внедрить экземпляр типа IServiceProvider.

public class DefaultController : Controller
{
    private IServiceProvider _provider;
    public DefaultController(IServiceProvider provider)
    {
        _provider = provider;
    }
}

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

ICustomFileLogger logger = (ICustomFileLogger)_provider.GetService(typeof(ICustomFileLogger));

Обратите внимание, как метод GetService IServiceProvider используется для получения экземпляра службы.

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

ICustomFileLogger logger = (ICustomFileLogger)HttpContext.RequestServices.GetService(typeof(ICustomFileLogger));

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

Related Posts

Оставить комментарий