← Назад к вопросам

Что такое AddTransient?

2.0 Middle🔥 241 комментариев
#Dependency Injection и IoC

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое AddTransient?

AddTransient — это метод расширения в ASP.NET Core, который регистрирует службу в контейнере внедрения зависимостей (DI, Dependency Injection) с временем жизни Transient (временное, транзиентное). Это означает, что каждый раз, когда запрашивается экземпляр этой службы (например, через конструктор или прямо из контейнера), создаётся новый объект.

Ключевые характеристики Transient-служб

  • Новый экземпляр на каждый запрос: Для каждого обращения к IServiceProvider.GetService<T>() или при каждом внедрении зависимости в конструктор создаётся новый объект.
  • Короткое время жизни: Экземпляры не отслеживаются и не удаляются контейнером. Сборщик мусора (GC) освобождает их память, когда они становятся недостижимыми.
  • Не подходят для хранения состояния: Из-за постоянного создания новых экземпляров они непригодны для хранения состояния между несколькими запросами в рамках одного HTTP-запроса или между запросами.

Типичные сценарии использования

AddTransient идеально подходит для:

  1. Легковесных служб без состояния: Например, валидаторы, преобразователи данных, простые утилиты.
  2. Служб, зависящих от контекста выполнения: Если каждый вызов должен быть изолирован (например, генератор случайных чисел с уникальным сидом).
  3. Служб, чьё создание дешёвое: Поскольку они создаются часто, их инициализация не должна быть ресурсоёмкой.

Регистрация и использование

В методе 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) создаются один раз на всё время работы приложения и используются повторно.

Риски и предостережения

  1. Циклические зависимости: Если Transient-служба A зависит от Transient-службы B, и наоборот, контейнер DI выбросит исключение при разрешении.
  2. Утечки памяти: Если Transient-служба реализует IDisposable, её необходимо явно освобождать, так как контейнер не отслеживает её время жизни. В ASP.NET Core, однако, контейнер обычно вызывает Dispose для Transient-служб, созданных внутри области видимости (scope), но это поведение может варьироваться.
  3. Производительность: Частое создание сложных объектов может снизить производительность. В таких случаях рассмотрите AddScoped или AddSingleton.

Заключение

AddTransient — это мощный инструмент для регистрации лёгких, не имеющих состояния, изолированных служб. Он обеспечивает максимальную гибкость и изоляцию, но требует осознанного выбора в зависимости от контекста и требований к времени жизни объекта. Правильное использование трёх типов регистрации (Transient, Scoped, Singleton) — ключ к созданию эффективного и поддерживаемого приложения на ASP.NET Core с грамотной работой контейнера внедрения зависимостей.