Как определяется срок существования объекта после его регистрации в контейнере внедрения зависимостей?
Ответ от нейросети
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будет жить весь срок работы приложения.
Пояснение кода:
Код показывает три варианта регистрации.
AddScoped<IUserContext, UserContext>()— контейнер создастUserContextодин раз внутри текущей области видимости.AddTransient<IEmailSender, EmailSender>()— каждый запрос зависимости получит новый объектEmailSender.AddSingleton<ICache, MemoryCacheService>()— первый запрос создаст экземпляр, а дальше будет использоваться тот же самый объект.
Если код не использовать, это можно описать так: срок жизни зависит не от самого класса, а от способа его регистрации в контейнере и от того, в каком scope происходит разрешение зависимости.
Ключевые моменты:
- Срок жизни задается при регистрации зависимости, а не в самом классе.
Transient— новый объект каждый раз.Scoped— один объект на scope.Singleton— один объект на весь контейнер/приложение.- Контейнер также отвечает за освобождение объектов, если они реализуют
IDisposable. - Ошибки чаще всего возникают при смешивании lifetimes, например когда singleton зависит от scoped-сервиса.