Зачем использовать AddScoped() вместо AddSingleton()?

Почему я должен использовать AddScoped() для своих репозиториев или сервисов? Почему бы и нет AddSingleton()? Я знаю о различиях между ними, но не понимаю, почему я не должен использовать экземпляры singleton, чтобы не создавать новые объекты для каждого запроса. Можете ли вы объяснить это (желательно с примерами:))?

AddSingleton() — это одноэлементный режим, он уникален во всем контейнере, поэтому при запуске программы его экземпляр уникален. AddScoped() уникален в конкретном домене, и домены не влияют друг на друга.

Qing Guo 13.05.2022 07:26

Пример. Если вы используете Entity Framework в качестве ORM, вы не можете зарегистрировать DbContext как Singleton, поскольку он не является потокобезопасным. Поэтому вы должны зарегистрировать его как переходный через AddDbContext.

Peter Csala 13.05.2022 07:48

Все дело в сохранении состояния, специфичного для запроса. Существует две модели хранения состояния, зависящего от запроса. В одна модель вы фиксируете данные времени выполнения в переменных объектов на вашем графике. Это требует использования Scoped образа жизни. Но есть другая модель, который хранит данные времени выполнения вне разрешенных объектов и сохраняет их как внешние данные. Это позволяет регистрировать объекты как синглтоны, потому что сами они не имеют никакого состояния.

Steven 13.05.2022 09:46
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Следующие три метода определяют время жизни сервисов,

  1. AddTransient Временные сервисы жизненного цикла создаются каждый раз, когда они запрашиваются. Это время жизни лучше всего подходит для облегченных служб без сохранения состояния.

  2. AddScoped Службы с ограниченным сроком службы создаются один раз для каждого запроса.

  3. AddSingleton Службы времени жизни Singleton создаются при первом запросе (или при запуске ConfigureServices, если вы укажете там экземпляр), а затем каждый последующий запрос будет использовать один и тот же экземпляр.

Ссылка здесь

Представьте, что у вас есть проект aspnet-core.

  • Если вы хотите создать объект только один раз во время выполнения программы и каждый раз использовать один и тот же объект, вы должны использовать addingleton.

  • Если вы хотите, чтобы объект снова был new() каждый раз, когда он получает запрос во время работы программы, вы должны использовать addscoped().

  • Если вы хотите, чтобы объект вызывал new() при каждом запросе и ответе, вы должны использовать AddTransient.

Пример значения 3 методов

Понимание с инфографикой

В типичном случае определение Scoped верно :) С технической точки зрения Scoped сервисы создаются не один раз для каждого запроса, а один раз для каждого сервиса. Просто так получается, что ASP.NET Core создает область для каждого запроса. Но вы также можете создать свои собственные области видимости в приложении, которые будут получать разные экземпляры, даже если это было во время одного и того же запроса.

juunas 13.05.2022 07:50

@juunas, ты можешь отредактировать мой ответ?

KOMODO 13.05.2022 10:08
Ответ принят как подходящий

Как вы сказали, вы знаете разницу, поэтому я не буду вдаваться в подробности.

Причина, по которой вам не нужен addSingleton для ваших репозиториев или служб, заключается в том, что обычно ваши репозитории и службы считаются «бизнес-логикой» и «логикой постоянства». И в вашей бизнес-логике у вас могут быть некоторые переменные уровня класса, которые устанавливаются. Эти свойства не будут различаться для каждого запроса, они будут общими для всех запросов. (думайте о них как о статических свойствах).

Пример:

Представьте, что у вас есть пользовательский сервис, который устанавливает имя пользователя, делающего запрос, как переменную уровня класса.

Логика синглтона:

Теперь представьте, что Боб делает запрос к API. Имя пользователя будет установлено на «Боб». А теперь представьте, в это же время Джон делает запрос к апи. Имя пользователя будет установлено на «Джон». Но поскольку пользовательский сервис является одноэлементным, и Джон, и Боб используют один и тот же экземпляр, а это означает, что имя пользователя Боба также будет установлено на «Джон».

Логика области действия:

Представьте точно такой же сценарий, как и выше, но на этот раз, когда Джон делает запрос, он не переопределяет имя пользователя bobs, потому что это разные экземпляры.

Другие вопросы по теме