Ответ вслух Middle ASP.NET Core спрашивают часто обновлено

Внедрение зависимостей в ASP.NET Core

Вопрос

Как работает встроенный DI-контейнер ASP.NET Core и какие ошибки с ним бывают?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Встроенный контейнер простой: сервисы регистрируются в IServiceCollection с временем жизни, а при создании контроллера или другого сервиса IServiceProvider смотрит на конструктор и рекурсивно создаёт зависимости. Главное правило: сервис не должен захватывать зависимость с более коротким временем жизни.

Что должно прозвучать в ответе

  • Регистрация в IServiceCollection, разрешение через IServiceProvider, внедрение через конструктор

  • Три времени жизни и правило не зависеть от более короткоживущих

  • Captive dependency и ValidateScopes

  • Scope вручную через IServiceScopeFactory в синглтонах и фоновых службах

  • Освобождение IDisposable контейнером

  • Service locator как антипаттерн

Что могут спросить следом

  • Как получить scoped-сервис в BackgroundService?
  • Почему не стоит внедрять IServiceProvider в бизнес-классы?

Разбор

Встроенный контейнер простой: сервисы регистрируются в IServiceCollection с временем жизни, а при создании контроллера или другого сервиса IServiceProvider смотрит на конструктор и рекурсивно создаёт зависимости.

Главное правило: сервис не должен захватывать зависимость с более коротким временем жизни. Если синглтон получит scoped DbContext, тот станет общим для всех запросов. В Development это ловит проверка ValidateScopes. В фоновых службах и синглтонах scoped-сервисы получают через IServiceScopeFactory.CreateScope() на каждую единицу работы.

Контейнер сам вызывает Dispose у созданных им объектов при закрытии scope, поэтому вручную освобождать внедрённые сервисы не нужно. Чего избегаю: внедрять IServiceProvider и вытаскивать зависимости по месту. Это service locator, зависимости становятся неявными, а тесты сложнее. Для нескольких реализаций одного интерфейса использую IEnumerable<T> или keyed services из .NET 8.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.