Правильно ли внедрять поставщика услуг, когда мне нужно получить несколько экземпляров зависимости из одного элемента?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. But it just seems... wrong to pass the service provider around.
The other obvious option is a factory pattern, in which I inject a MyWorkerFactory into MyBackgroundService, but that sort of just kicks the can down the road, where instead of MyBackgroundService taking in a bunch of dependencies it doesn't use, MyWorkerFactory does instead.
I thought at first simply внедрение класса MyWorker как временного решило бы проблему, пока я не понял, что Transient создает новый экземпляр для каждого экземпляра, который его запрашивает, но поскольку MyBackgroundService является одноэлементным, все равно будет только один MyWorker.
Как правильно это сделать?

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