Правильно ли внедрять поставщика услуг, когда мне нужно получить несколько экземпляров зависимости из одного элемента?C#

Место общения программистов C#
Anonymous
Правильно ли внедрять поставщика услуг, когда мне нужно получить несколько экземпляров зависимости из одного элемента?

Сообщение Anonymous »

У меня есть сервис, имеющий такую ​​структуру:

Код: Выделить всё

class MyBackgroundService : BackgroundService
{
// ...
Dictionary _workers

public MyBackgroundService(/*a bunch of injected dependencies*/)
{
// store the injected dependencies in private fields
}

protected override Task ExecuteAsync(CancellationToken token)
{
while (true)
{
if (_myWatcher.GetNewConfigurations(out var newConfigurations)
{
foreach (var newConfiguration in newConfigurations)
{
_workers[newConfiguration.Id] = new MyWorker(/*pass in all the injected private fields*/);
}
}

// some code to remove workers that are no longer needed from the dictionary
// some code to break out of the loop when appropriate
}
}

// ...
}
По сути, существует внешняя служба конфигурации, которую моя служба опрашивает на наличие новых конфигураций, и после ее получения мой класс запускает нового рабочего для новой конфигурации.

Код: Выделить всё

MyBackgroundService
является синглтоном, поэтому существует только один его экземпляр. Поскольку у меня есть несколько внедренных зависимостей, которые мне сейчас нужно внедрить в MyBackgroundService, которые на самом деле ни для чего не используются, мне интересно, не следует ли вместо этого просто внедрить сам ServiceProvider и вызвать GetService(), чтобы создать экземпляр нового экземпляра класса MyWorker при обнаружении новой конфигурации, например:

Код: Выделить всё

class MyBackgroundService : BackgroundService
{
// ...
Dictionary _workers
private readonly IServiceProvider _serviceProvider;

public MyBackgroundService(IServiceProvider sp)
{
_serviceProvider = sp;
}

protected override Task ExecuteAsync(CancellationToken token)
{
while (true)
{
if (_myWatcher.GetNewConfigurations(out var newConfigurations)
{
foreach (var newConfiguration in newConfigurations)
{
_workers[newConfiguration.Id] = _serviceProvider.GetService();
}
}

// some code to remove workers that are no longer needed from the dictionary
// some code to break out of the loop when appropriate
}
}

// ...
}
Этот код чище, поскольку MyBackgroundService не принимает кучу зависимостей, которые нужны только для создания экземпляров MyWorker. Но кажется... неправильным передавать поставщика услуг другим.
Другой очевидный вариант — это фабричный шаблон, в котором я добавляю MyWorkerFactory в MyBackgroundService, но это своего рода просто отбрасывает банку в сторону, где вместо MyBackgroundService, принимающего кучу зависимостей, которые он не использует, вместо этого это делает MyWorkerFactory.
Сначала я думал просто внедрение класса MyWorker как временного решило бы проблему, пока я не понял, что Transient создает новый экземпляр для каждого экземпляра, который его запрашивает, но поскольку MyBackgroundService является одноэлементным, все равно будет только один MyWorker.
Как правильно это сделать?

Вернуться в «C#»