В ASP.NET Core Dependency Injection существует три основных времени жизни сервисов:
Характеристики:
Пример использования:
services.AddTransient<IEmailService, EmailService>();
Когда использовать:
Характеристики:
Пример использования:
services.AddScoped<IUserRepository, UserRepository>();
Когда использовать:
Пример с Transient:
// Регистрация
services.AddTransient<IOperation, Operation>();
// В контроллере
public class TestController : Controller
{
private readonly IOperation _op1;
private readonly IOperation _op2;
public TestController(IOperation op1, IOperation op2)
{
// op1 и op2 - РАЗНЫЕ экземпляры
_op1 = op1;
_op2 = op2;
}
}
Пример с Scoped:
// Регистрация
services.AddScoped<IOperation, Operation>();
// В контроллере
public class TestController : Controller
{
private readonly IOperation _op1;
private readonly IOperation _op2;
public TestController(IOperation op1, IOperation op2)
{
// op1 и op2 - ОДИН И ТОТ ЖЕ экземпляр в рамках запроса
_op1 = op1;
_op2 = op2;
}
}
Пример создания scope вручную:
using (var scope = serviceProvider.CreateScope())
{
var scopedService = scope.ServiceProvider.GetRequiredService<IMyScopedService>();
// Работа с scopedService
}
Использование Scoped сервиса в Singleton:
services.AddSingleton<IBackgroundService>(provider =>
new BackgroundService(provider.GetRequiredService<IScopedService>())); // ОШИБКА!
Использование Transient для тяжелых сервисов:
services.AddTransient<IDatabaseService>(_ =>
new DatabaseService(heavyConnection)); // Неэффективно
Основное различие между AddTransient
и AddScoped
заключается в времени жизни создаваемых экземпляров сервисов. AddTransient
создает новый экземпляр при каждом запросе сервиса, в то время как AddScoped
создает один экземпляр на область видимости (обычно HTTP-запрос). Правильный выбор между ними критически важен для корректной работы приложения, управления ресурсами и предотвращения subtle bugs.