Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое AddTransient?
AddTransient — это метод расширения в ASP.NET Core, который регистрирует службу в контейнере внедрения зависимостей (DI, Dependency Injection) с временем жизни Transient (временное, транзиентное). Это означает, что каждый раз, когда запрашивается экземпляр этой службы (например, через конструктор или прямо из контейнера), создаётся новый объект.
Ключевые характеристики Transient-служб
- Новый экземпляр на каждый запрос: Для каждого обращения к
IServiceProvider.GetService<T>()или при каждом внедрении зависимости в конструктор создаётся новый объект. - Короткое время жизни: Экземпляры не отслеживаются и не удаляются контейнером. Сборщик мусора (GC) освобождает их память, когда они становятся недостижимыми.
- Не подходят для хранения состояния: Из-за постоянного создания новых экземпляров они непригодны для хранения состояния между несколькими запросами в рамках одного HTTP-запроса или между запросами.
Типичные сценарии использования
AddTransient идеально подходит для:
- Легковесных служб без состояния: Например, валидаторы, преобразователи данных, простые утилиты.
- Служб, зависящих от контекста выполнения: Если каждый вызов должен быть изолирован (например, генератор случайных чисел с уникальным сидом).
- Служб, чьё создание дешёвое: Поскольку они создаются часто, их инициализация не должна быть ресурсоёмкой.
Регистрация и использование
В методе ConfigureServices класса Startup или в файле Program.cs вы регистрируете службу следующим образом:
public void ConfigureServices(IServiceCollection services)
{
// Регистрируем IEmailSender и его реализацию EmailSender как Transient
services.AddTransient<IEmailSender, EmailSender>();
// Регистрируем конкретный тип без интерфейса (реже, но возможно)
services.AddTransient<DataValidator>();
// Можно использовать фабричную функцию для сложной логики создания
services.AddTransient<IConnection>(serviceProvider =>
{
var config = serviceProvider.GetRequiredService<IConfiguration>();
return new SqlConnection(config.GetConnectionString("Default"));
});
}
Практический пример
Представьте простой сервис для генерации идентификаторов:
public interface IIdGenerator
{
string GenerateId();
}
public class GuidIdGenerator : IIdGenerator
{
public string GenerateId() => Guid.NewGuid().ToString();
}
Регистрация:
services.AddTransient<IIdGenerator, GuidIdGenerator>();
Использование в контроллере:
public class OrderController : ControllerBase
{
private readonly IIdGenerator _idGenerator;
// При каждом запросе к контроллеру внедряется НОВЫЙ экземпляр GuidIdGenerator
public OrderController(IIdGenerator idGenerator)
{
_idGenerator = idGenerator;
}
[HttpPost]
public IActionResult CreateOrder()
{
var orderId = _idGenerator.GenerateId(); // Уникальный GUID для каждого вызова
// Логика создания заказа...
return Ok(new { id = orderId });
}
}
Важные отличия от других времён жизни
- Transient vs Scoped: Scoped-службы (добавляемые через
AddScoped) создаются один раз на область видимости (обычно на HTTP-запрос). Например,DbContextв EF Core регистрируется как Scoped, чтобы все операции в рамках одного запроса использовали один контекст. - Transient vs Singleton: Singleton-службы (добавляемые через
AddSingleton) создаются один раз на всё время работы приложения и используются повторно.
Риски и предостережения
- Циклические зависимости: Если Transient-служба A зависит от Transient-службы B, и наоборот, контейнер DI выбросит исключение при разрешении.
- Утечки памяти: Если Transient-служба реализует
IDisposable, её необходимо явно освобождать, так как контейнер не отслеживает её время жизни. В ASP.NET Core, однако, контейнер обычно вызываетDisposeдля Transient-служб, созданных внутри области видимости (scope), но это поведение может варьироваться. - Производительность: Частое создание сложных объектов может снизить производительность. В таких случаях рассмотрите
AddScopedилиAddSingleton.
Заключение
AddTransient — это мощный инструмент для регистрации лёгких, не имеющих состояния, изолированных служб. Он обеспечивает максимальную гибкость и изоляцию, но требует осознанного выбора в зависимости от контекста и требований к времени жизни объекта. Правильное использование трёх типов регистрации (Transient, Scoped, Singleton) — ключ к созданию эффективного и поддерживаемого приложения на ASP.NET Core с грамотной работой контейнера внедрения зависимостей.