Основные Заблуждения о Внедрении Зависимостей в ASP.NET Core. Начало
Разработчики, которые недавно начали работать с внедрением зависимостей в ASP.NET Core, часто неверно понимают принципы его работы. Некоторые заблуждения вызывают ошибки, а другие приводят к избыточному коду. Рассмотрим наиболее распространённые.
1. Scoped сервис создаётся только один раз для каждого веб-запроса
Разработчики могут выбрать время жизни сервиса при внедрении зависимости:
- Transient - новый экземпляр класса создается каждый раз, когда он запрашивается из контейнера DI,
- Singleton - один экземпляр класса будет создан на всё время существования приложения,
- Scoped - экземпляр класса должен быть создан один раз для каждого веб-запроса.
services.AddScoped<IUserRepository, UserRepository>();Однако время жизни, ограниченное областью действия, (scoped) не гарантирует, что класс создаётся только один раз для каждого веб-запроса. Это означает, что класс будет создан только один раз в заданной области действия, но в одном веб-запросе можно создать несколько областей.
Область действия - это область кода между созданием экземпляра типа
IServiceScope и вызовом его метода Dispose. IServiceScope содержит свойство ServiceProvider, которое используется для разрешения экземпляров сервисов, зарегистрированных в методе ConfigureServices.Если один и тот же тип в области действия запрашивается несколько раз, всегда будет возвращаться один и тот же экземпляр. ASP.NET Core создаёт область действия в начале веб-запроса и удаляет её в конце веб-запроса. Поэтому экземпляры, ограниченные областью действия, создаются один раз для каждого веб-запроса. Но не всегда.
Ничто не мешает разработчикам создавать дочерние области действия. Экземпляры одного и того же типа, разрешённые из разных областей действия, также будут разными:
public class SomeServiceБывают случаи, когда создание области вручную - это единственный правильный способ получить экземпляр сервиса, например, для разрешения scoped сервиса из синглтона. Знание особенностей областей действия может защитить вас от множества проблем.
{
private readonly IServiceScopeFactory _factory;
public SomeService(IServiceScopeFactory factory)
=> _factory = factory;
public void DoSomething()
{
using (IServiceScope scope = _factory.CreateScope());
var obj1 =
scope.ServiceProvider.GetService<IUserRepository>();
using (IServiceScope childScope =
_factory.CreateScope())
{
var obj2 = childScope.ServiceProvider
.GetService<IUserRepository>();
if (obj1 != obj2)
Console.WriteLine("Экземпляры разные.");
}
}
}
Продолжение следует…
Источник: https://levelup.gitconnected.com/top-misconceptions-about-dependency-injection-in-asp-net-core-c6a7afd14eb4