← Назад к вопросам

Что такое AddSingleton?

2.0 Middle🔥 81 комментариев
#Dependency Injection и IoC

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое AddSingleton в ASP.NET Core?

AddSingleton — это метод расширения для регистрации сервисов в контейнере внедрения зависимостей (Dependency Injection, DI) ASP.NET Core с singleton-жизненным циклом. Это означает, что контейнер создаст только один экземпляр зарегистрированного сервиса на всё время работы приложения, и этот экземпляр будет переиспользоваться для всех запросов и всех потребителей.

Основные характеристики AddSingleton

  1. Единственный экземпляр на всё приложение: Контейнер создаёт экземпляр при первом обращении (или при старте приложения, в зависимости от способа регистрации) и затем всегда возвращает этот же экземпляр.
  2. Потокобезопасность: Поскольку экземпляр один, необходимо самостоятельно обеспечивать потокобезопасность, если сервис используется параллельно в нескольких запросах.
  3. Подходит для 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.
  • Сервисы с общим состоянием: Например, счётчик запросов или общий буфер данных.

Важные предостережения

  1. Не используйте для сервисов с состоянием, зависящим от запроса: Если сервис хранит данные конкретного пользователя или запроса — используйте AddScoped.
  2. Потокобезопасность: Singleton-сервисы должны быть спроектированы как потокобезопасные, так как они используются параллельно.
  3. Disposable-сервисы: Если singleton реализует IDisposable, контейнер автоматически вызовет Dispose() при завершении работы приложения.

Сравнение с другими жизненными циклами

Метод регистрацииВремя жизни экземпляраТипичное использование
AddSingletonНа всё время работы приложенияКэши, конфигурации, логгеры
AddScopedНа время обработки одного запросаРабота с БД (DbContext), сервисы с состоянием запроса
AddTransientСоздаётся новый для каждой зависимостиЛегковесные сервисы без состояния

Внутренняя реализация

Контейнер DI в ASP.NET Core хранит singleton-сервисы в корневом контейнере (root container), который не уничтожается до завершения приложения. Это отличается от scoped-сервисов, которые хранятся в контейнерах области видимости (scope), создаваемых для каждого запроса.

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