Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое AddSingleton в ASP.NET Core?
AddSingleton — это метод расширения для регистрации сервисов в контейнере внедрения зависимостей (Dependency Injection, DI) ASP.NET Core с singleton-жизненным циклом. Это означает, что контейнер создаст только один экземпляр зарегистрированного сервиса на всё время работы приложения, и этот экземпляр будет переиспользоваться для всех запросов и всех потребителей.
Основные характеристики AddSingleton
- Единственный экземпляр на всё приложение: Контейнер создаёт экземпляр при первом обращении (или при старте приложения, в зависимости от способа регистрации) и затем всегда возвращает этот же экземпляр.
- Потокобезопасность: Поскольку экземпляр один, необходимо самостоятельно обеспечивать потокобезопасность, если сервис используется параллельно в нескольких запросах.
- Подходит для stateless-сервисов: Идеально для сервисов без состояния (например, кэши, логгеры, конфигурации) или с общим состоянием, которое должно быть доступно всем.
Способы регистрации через AddSingleton
1. Регистрация типа (Type)
Контейнер сам создаёт экземпляр при необходимости:
services.AddSingleton<IMyService, MyService>();
Здесь IMyService — интерфейс (или абстрактный тип), MyService — конкретная реализация.
2. Регистрация существующего экземпляра (Instance)
Передаётся уже созданный объект, который контейнер будет использовать как singleton:
var myService = new MyService();
services.AddSingleton<IMyService>(myService);
3. Регистрация через фабричный метод (Factory)
Контейнер вызывает переданную функцию для создания экземпляра при первом обращении:
services.AddSingleton<IMyService>(serviceProvider =>
{
var otherService = serviceProvider.GetRequiredService<IOtherService>();
return new MyService(otherService);
});
Пример использования
Рассмотрим практический пример с кэшем в памяти:
public interface ICacheService
{
void Add(string key, object value);
object Get(string key);
}
public class MemoryCacheService : ICacheService
{
private readonly ConcurrentDictionary<string, object> _cache = new();
public void Add(string key, object value)
{
_cache[key] = value;
}
public object Get(string key)
{
_cache.TryGetValue(key, out var value);
return value;
}
}
// Регистрация в Startup.cs или Program.cs
services.AddSingleton<ICacheService, MemoryCacheService>();
// Использование в контроллере
public class ProductsController : ControllerBase
{
private readonly ICacheService _cache;
public ProductsController(ICacheService cache)
{
_cache = cache; // Все экземпляры ProductsController получат один и тот же объект cache
}
}
Когда использовать AddSingleton?
- Сервисы без состояния: Логгеры, кэши, конфигурации, мапперы (AutoMapper).
- Дорогие в создании объекты: Подключения к базам данных (хотя для БД чаще используют Scoped), тяжеловесные клиенты API.
- Сервисы с общим состоянием: Например, счётчик запросов или общий буфер данных.
Важные предостережения
- Не используйте для сервисов с состоянием, зависящим от запроса: Если сервис хранит данные конкретного пользователя или запроса — используйте AddScoped.
- Потокобезопасность: Singleton-сервисы должны быть спроектированы как потокобезопасные, так как они используются параллельно.
- Disposable-сервисы: Если singleton реализует
IDisposable, контейнер автоматически вызоветDispose()при завершении работы приложения.
Сравнение с другими жизненными циклами
| Метод регистрации | Время жизни экземпляра | Типичное использование |
|---|---|---|
| AddSingleton | На всё время работы приложения | Кэши, конфигурации, логгеры |
| AddScoped | На время обработки одного запроса | Работа с БД (DbContext), сервисы с состоянием запроса |
| AddTransient | Создаётся новый для каждой зависимости | Легковесные сервисы без состояния |
Внутренняя реализация
Контейнер DI в ASP.NET Core хранит singleton-сервисы в корневом контейнере (root container), который не уничтожается до завершения приложения. Это отличается от scoped-сервисов, которые хранятся в контейнерах области видимости (scope), создаваемых для каждого запроса.
AddSingleton — мощный инструмент для оптимизации производительности и управления общими ресурсами, но требующий внимательного проектирования с учётом многопоточности и состояния сервисов.