使用BuildServiceProvider时单例的多个实例

问题描述 投票:0回答:1

我正在尝试创建一个作为后台服务运行的依赖注入管道服务。 我的想法是,我可以创建“一对多”这些服务,并为每个步骤中需要更改的一些值(使用服务密钥加载)传入简单的 IOption 配置,我将它们注册为一个密钥服务,这样它们就不会覆盖彼此。 我还有一个作为单例创建的队列管理器,它允许我根据也在 IOptions 配置中传递的队列配置获取生产者/消费者。

我为要创建的管道的每个版本传递不同的服务密钥

我的代码的简单版本(下面只是基础知识)

public IServiceCollection AddPipelineService(this IServiceCollection services, IConfigurationManager configuration, string serviceKey) { // Get Config for the steps based on the sevice key var StepOptions = Options.Create( configuration .GetSection($"{serviceKey}:{StepOptions.StepOptionsName}") .Get<MessageFactoryOptions>()); // Build a list of steps and reister a service services.AddKeyedSingleton<IStep, Step1>(serviceKey, (p,o) => new Step1(p.GetRequiredService<ILogger<ConfirmResponseMessageFactory>>(), stepOptions); services.AddKeyedSingleton<IStep, Step2>(serviceKey, (p, o) => new Step2(p.GetRequiredService<ILogger<ConfirmResponseMessageFactory>>(), stepOptions); services.AddKeyedSingleton<IStep, Step3>(serviceKey, (p, o) => new Step3(p.GetRequiredService<ILogger<ConfirmResponseMessageFactory>>(), stepOptions); // Create the service provider var provider = services.BuildServiceProvider(validateScopes: true); // Add the steps to a set collection IEnumerable<IStep> steps = provider.GetKeyedServices<IMessageProcessItem>(serviceKey); services.AddKeyedSingleton<IStepCollection, StepCollection>(serviceKey, (p, o) => new StepCollection(steps)); // Create the queue options based on the service key var queueOptions = Options.Create( configuration .GetSection($"{serviceKey}:{QueueOptions.QueueOptionsName}") .Get<MessageFactoryOptions>()); // NOTE // IQueueManager registered earlier as a singleton (i only want to onpen a siingle connection and reuse for creation of consumers and producers) // PipelineBackgroundService is a BackgroundService services.AddSingleton<IHostedService, PipelineBackgroundService>( p => new PipelineBackgroundService( p.GetRequiredService<ILogger<PipelineBackgroundService>>(), p.GetRequiredService<IQueueManager>(), p.GetRequiredKeyedService<IStepCollection>(serviceKey), queueOptions); return services; }

所有这些都有效,但我最终得到了多个版本的队列管理器,因为我调用 
BuildServiceProvider

,我相信它创建了一个新容器。 但我读过我应该避免使用BuildServiceProvider 有没有一种方法可以在不产生这种副作用并且不使用 BuildServiceProvider 的情况下做到这一点。

谢谢, 尼克

c# dependency-injection c#-8.0 servicecollection
1个回答
0
投票

services.AddKeyedSingleton<IStepCollection, StepCollection>(serviceKey, (p, o) => new StepCollection(p.GetKeyedServices<IMessageProcessItem>(serviceKey)));

现在只创建了 QueueManager 的一个实例

© www.soinside.com 2019 - 2024. All rights reserved.