Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое AddScoped в .NET Core?
AddScoped — это метод регистрации зависимостей в контейнере внедрения зависимостей (DI Container) ASP.NET Core, который обеспечивает создание одного экземпляра сервиса в пределах одной области (scope), обычно соответствующей одному HTTP-запросу в веб-приложениях.
Основной принцип работы
При использовании AddScoped контейнер DI создаёт один и тот же экземпляр сервиса для всех запросов внутри одной области. Для нового запроса (новой области) создаётся новый экземпляр. Это особенно полезно для сервисов, которые хранят состояние в течение обработки одного запроса, таких как репозитории, сервисы бизнес-логики или контексты базы данных.
// Пример регистрации scoped-сервиса в Startup.cs или Program.cs
services.AddScoped<IMyService, MyService>();
Отличие от других типов регистрации
В ASP.NET Core существуют три основных времени жизни сервисов:
- Singleton (
AddSingleton) — один экземпляр на всё время работы приложения. - Scoped (
AddScoped) — один экземпляр на область (обычно HTTP-запрос). - Transient (
AddTransient) — новый экземпляр при каждом запросе.
Практическое применение
Scoped-сервисы идеально подходят для:
- Entity Framework DbContext — чтобы все операции в рамках одного запроса использовали один контекст
- Сервисы с состоянием, специфичным для запроса
- Репозитории, которые должны разделять единицу работы
public class OrderService : IOrderService
{
private readonly ApplicationDbContext _context;
// DbContext будет одним и тем же экземпляром в рамках запроса
public OrderService(ApplicationDbContext context)
{
_context = context;
}
public async Task ProcessOrder(Order order)
{
// Все операции используют один контекст
_context.Orders.Add(order);
await _context.SaveChangesAsync();
}
}
// Регистрация
services.AddScoped<IOrderService, OrderService>();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Области видимости (Scopes)
Область создаётся автоматически для каждого HTTP-запроса в ASP.NET Core, но вы также можете создавать области вручную:
using (var scope = serviceProvider.CreateScope())
{
var scopedService = scope.ServiceProvider.GetRequiredService<IMyScopedService>();
// Работа с scopedService
// После выхода из using область уничтожается, а с ней и scoped-сервисы
}
Важные особенности
-
Потокобезопасность — Scoped-сервисы не предназначены для использования между потоками, так как область обычно ограничена одним потоком выполнения запроса.
-
Внедрение зависимостей — Scoped-сервисы могут быть внедрены только в:
- Другие scoped-сервисы
- Transient-сервисы
- Конструкторы контроллеров (так как контроллеры создаются на каждый запрос)
-
Ограничения — Singleton-сервисы не могут зависеть от scoped-сервисов, так как singleton живёт дольше любой области.
-
Распределённые приложения — В сценариях с несколькими экземплярами приложения каждый экземпляр имеет свои собственные scoped-сервисы.
Типичные ошибки
// НЕПРАВИЛЬНО: Singleton зависит от Scoped
services.AddSingleton<ISingletonService>(provider =>
new SingletonService(provider.GetRequiredService<IScopedService>())); // Исключение!
// ПРАВИЛЬНО: Использование фабрики для получения scoped-сервиса при необходимости
services.AddSingleton<ISingletonService>(provider =>
new SingletonService(() => provider.CreateScope()
.ServiceProvider.GetRequiredService<IScopedService>()));
Заключение
AddScoped — это фундаментальный механизм управления временем жизни сервисов в ASP.NET Core, который обеспечивает баланс между производительностью (меньше созданий объектов, чем transient) и изоляцией данных (лучше, чем singleton). Правильное использование scoped-сервисов критически важно для создания масштабируемых и безопасных веб-приложений, особенно при работе с базами данных и состояниями, специфичными для пользовательских сессий.