Sobes.tech
Назад к вопросам
Junior — Middle
62

Как определяется срок существования объекта после его регистрации в контейнере внедрения зависимостей?

Компании, где спрашивали
OZONOZON

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Срок жизни объекта в DI-контейнере определяется тем, с каким временем жизни он был зарегистрирован: transient, scoped или singleton. Контейнер сам управляет созданием и, в ряде случаев, повторным использованием экземпляра. Важно понимать, где именно объект будет переиспользоваться и кто отвечает за его освобождение.

Определение:

После регистрации в контейнере внедрения зависимостей объект не существует сам по себе — контейнер создает его по запросу и хранит в соответствии с выбранным lifetime.
Обычно выделяют три базовых варианта:

  • Transient — новый экземпляр создается каждый раз при запросе.
  • Scoped — один экземпляр используется в рамках одного scope, например одного HTTP-запроса.
  • Singleton — один экземпляр создается один раз и используется до завершения работы приложения или контейнера.

Именно тип регистрации определяет, как долго объект будет жить и когда контейнер его уничтожит.

Пример использования:

Например, сервис для работы с временными данными запроса обычно регистрируют как Scoped, чтобы в рамках одного HTTP-запроса использовался один и тот же экземпляр.

services.AddScoped<IUserContext, UserContext>();
services.AddTransient<IEmailSender, EmailSender>();
services.AddSingleton<ICache, MemoryCacheService>();

В этом примере:

  • UserContext будет один на запрос;
  • EmailSender будет создаваться заново при каждом внедрении;
  • MemoryCacheService будет жить весь срок работы приложения.

Пояснение кода:

Код показывает три варианта регистрации.

  1. AddScoped<IUserContext, UserContext>() — контейнер создаст UserContext один раз внутри текущей области видимости.
  2. AddTransient<IEmailSender, EmailSender>() — каждый запрос зависимости получит новый объект EmailSender.
  3. AddSingleton<ICache, MemoryCacheService>() — первый запрос создаст экземпляр, а дальше будет использоваться тот же самый объект.

Если код не использовать, это можно описать так: срок жизни зависит не от самого класса, а от способа его регистрации в контейнере и от того, в каком scope происходит разрешение зависимости.

Ключевые моменты:

  • Срок жизни задается при регистрации зависимости, а не в самом классе.
  • Transient — новый объект каждый раз.
  • Scoped — один объект на scope.
  • Singleton — один объект на весь контейнер/приложение.
  • Контейнер также отвечает за освобождение объектов, если они реализуют IDisposable.
  • Ошибки чаще всего возникают при смешивании lifetimes, например когда singleton зависит от scoped-сервиса.