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

Что такое scope factory?

1.3 Junior🔥 192 комментариев
#Основы C# и .NET

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

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

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

🏭 Что такое Scope Factory?

Scope Factory — это паттерн проектирования и конкретная реализация в .NET для создания скоупов зависимостей. По сути, это фабрика, которая создает новые экземпляры IServiceScope, позволяя управлять временем жизни зависимостей в контейнере вне стандартного жизненного цикла приложения.

🔍 Основная концепция и предназначение

В ASP.NET Core DI-контейнер имеет три основных времени жизни:

  • Singleton — один экземпляр на все приложение
  • Scoped — один экземпляр на область (scope), обычно на HTTP-запрос
  • Transient — новый экземпляр при каждом запросе

Scope Factory позволяет создавать новые области вручную, когда стандартной области HTTP-запроса недостаточно. Это особенно полезно в сценариях, где:

  1. Выполнение фоновых задач вне контекста HTTP-запроса
  2. Обработка сообщений из очереди (RabbitMQ, Azure Service Bus)
  3. Параллельная обработка данных в нескольких независимых областях
  4. Создание изолированных контекстов для транзакций БД

📦 Интерфейс IServiceScopeFactory

Основной интерфейс, представляющий Scope Factory:

public interface IServiceScopeFactory
{
    IServiceScope CreateScope();
}
public interface IServiceScope : IDisposable
{
    IServiceProvider ServiceProvider { get; }
}

💻 Практическое использование

Вот типичный пример использования Scope Factory в фоновом сервисе:

public class BackgroundProcessingService : BackgroundService
{
    private readonly IServiceScopeFactory _scopeFactory;
    private readonly ILogger<BackgroundProcessingService> _logger;

    public BackgroundProcessingService(
        IServiceScopeFactory scopeFactory,
        ILogger<BackgroundProcessingService> logger)
    {
        _scopeFactory = scopeFactory;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            // Создаем новую область для каждой итерации
            using (var scope = _scopeFactory.CreateScope())
            {
                // Получаем сервисы из новой области
                var dbContext = scope.ServiceProvider
                    .GetRequiredService<ApplicationDbContext>();
                var repository = scope.ServiceProvider
                    .GetRequiredService<IDataRepository>();
                
                // Выполняем работу с изолированными зависимостями
                await ProcessDataAsync(dbContext, repository);
            }
            
            await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
        }
    }
    
    private async Task ProcessDataAsync(
        ApplicationDbContext context, 
        IDataRepository repository)
    {
        // Каждый вызов получает свои собственные экземпляры
        // DbContext будет уникальным для каждой области
    }
}

🎯 Ключевые преимущества

Контроль времени жизни зависимостей:

  • Позволяет явно управлять временем существования Scoped-сервисов
  • Обеспечивает правильное освобождение ресурсов через Dispose

Изоляция контекстов:

  • Каждая область имеет собственный набор Scoped-сервисов
  • Предотвращает утечки данных между разными операциями

Гибкость архитектуры:

  • Можно создавать вложенные области
  • Поддерживает сложные сценарии обработки

⚠️ Важные аспекты реализации

Disposable-ресурсы:

// ВАЖНО: Всегда используйте using для IServiceScope
using (var scope = _scopeFactory.CreateScope())
{
    var service = scope.ServiceProvider.GetService<IMyService>();
    // работа с сервисом
} // Здесь автоматически вызовется Dispose для всех Scoped-сервисов

Особенности для DbContext в Entity Framework Core:

  • Каждая область получает свой экземпляр DbContext
  • Это позволяет параллельно выполнять операции с БД без конфликтов
  • Автоматическое управление подключениями и транзакциями

🔄 Альтернативы и сравнения

IServiceProvider vs IServiceScopeFactory:

  • IServiceProvider из корневого контейнера может создавать только Singleton
  • IServiceScopeFactory специально предназначен для создания областей

Внедрение зависимости:

// Предпочтительный способ - инжектировать фабрику
public class MyService
{
    private readonly IServiceScopeFactory _scopeFactory;
    
    public MyService(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
    }
}

// Вместо инжектирования IServiceProvider (менее явно)

🛠️ Реальные сценарии применения

  1. Обработка фоновых задач в HostedService
  2. Параллельная обработка элементов коллекции
  3. Создание отдельных контекстов для разных клиентов в SignalR
  4. Обработка сообщений из очереди с гарантией изоляции
  5. Выполнение миграций или seed данных при запуске приложения

📝 Заключение

Scope Factory — это мощный инструмент в арсенале .NET разработчика, который обеспечивает гибкое управление временем жизни зависимостей. Он особенно важен при работе с фоновыми задачами, параллельной обработкой и любыми сценариями, выходящими за рамки стандартного HTTP-запроса. Правильное использование этого паттерна позволяет создавать более надежные, масштабируемые и поддерживаемые приложения, избегая распространенных проблем с утечками памяти и конфликтами контекстов.

Что такое scope factory? | PrepBro