基于配置文件的具有不同参数的 class 的多个实例
Multiple instances of class with different parameters based on configuration file
所以我有一个简单的配置class PubsubSettings
:
public class PubSubSettings
{
public string ProjectId { get; set; }
public string TopicId { get; set; }
public int PartnerId { get; set; }
public string SubscriptionId { get; set; }
}
我以前只在我的 appsettings.json 中配置了其中一个,但现在我希望能够处理任意数量的它们。
我还有一个 class、PubSub
,我通常会在其中注入一个 IOptions<PubSubSettings>
。而这又被注入到我的 Worker
class.
services.Configure<PubSubSettings>(configuration.GetSection(nameof(PubSubSettings)));
...
services.AddHostedService<Worker>();
所以,我现在要做的是为我的 AppSettings PubSubSettings
部分中的每个条目添加一个新的 Worker
作为托管服务,并将相关的 IOptions<PubSubSettings>
注入每个其中(连同标准 ILogger
)。
所以本质上,我想要这个配置块:
"PubsubSettings": [
{
"ProjectId": "project1",
"TopicId": "topic",
"PartnerId": 1,
"SubscriptionId": "sub1"
},
{
"ProjectId": "project2",
"TopicId": "topic2",
"PartnerId": 2,
"SubscriptionId": "sub2"
}
]
最终创建两个托管服务,一个使用第一组选项,另一个使用第二组。
我已经看到一些问题在寻找类似的东西,但我找不到与此完全一致的东西,所以我有点难过。有什么想法吗?
解决方案是 Dotnet 5。
也许你可以尝试只为对象创建一个 class 并让 PubSubSettings class 只为数组:
public class PubSubSettings
{
public PubSubObject[] PubSubs { get; set; }
}
public class PubSubObject
{
public string ProjectId { get; set; }
public string TopicId { get; set; }
public int PartnerId { get; set; }
public string SubscriptionId { get; set; }
}
然后在启动时class你应该使用Bind
获取数组的当前值来为每个PubSub
创建一个Worker
:
PubSubSettings settings = new PubSubSettings();
Configuration.GetSection(nameof(PubSubSettings)).Bind(settings);
...
foreach(PubSubObject item in settings.PubSubs)
{
services.AddHostedService<Worker>();
}
然后在PubSub
class中你需要搜索Array里面的PartnerId
。
或者您可以按照 Microsoft 文档中命名选项支持使用 IConfigureNamedOptions 部分中描述的方法:Options pattern in ASP.NET Core
因此,根据我所能找到的,没有任何开箱即用的方法。
但是,这可以使用 ActivatorUtilities
和 Configuration.Bind()
的组合手动完成。
private void CreateWorkers(IServiceCollection services, IConfigurationRoot configuration)
{
List<PubSubSettings> pubsubSettings = new();
configuration.Bind(nameof(PubSubSettings), pubsubSettings);
foreach (PubSubSettings setting in pubsubSettings)
{
services.AddSingleton<IHostedService>(s => ActivatorUtilities.CreateInstance<Worker>(s, ActivatorUtilities.CreateInstance<PubSub.PubSub>(s, setting)));
}
}
本质上,您可以使用Bind
从JSON 中获取配置对象。然后您可以使用 CreateInstance
.
手动构造 Worker
以调用 AddHostedService
在这种情况下需要两次调用,一次为 worker 生成 PubSub
(我们在其中传递设置参数),另一次调用生成 Worker
本身。
ActivatorUtilities
本质上是注入对象所需的一切,除了您提供的参数。
我们需要使用 .AddSingleton<IHostedService>
因为 和 AddHostedService()
.
所以我有一个简单的配置class PubsubSettings
:
public class PubSubSettings
{
public string ProjectId { get; set; }
public string TopicId { get; set; }
public int PartnerId { get; set; }
public string SubscriptionId { get; set; }
}
我以前只在我的 appsettings.json 中配置了其中一个,但现在我希望能够处理任意数量的它们。
我还有一个 class、PubSub
,我通常会在其中注入一个 IOptions<PubSubSettings>
。而这又被注入到我的 Worker
class.
services.Configure<PubSubSettings>(configuration.GetSection(nameof(PubSubSettings)));
...
services.AddHostedService<Worker>();
所以,我现在要做的是为我的 AppSettings PubSubSettings
部分中的每个条目添加一个新的 Worker
作为托管服务,并将相关的 IOptions<PubSubSettings>
注入每个其中(连同标准 ILogger
)。
所以本质上,我想要这个配置块:
"PubsubSettings": [
{
"ProjectId": "project1",
"TopicId": "topic",
"PartnerId": 1,
"SubscriptionId": "sub1"
},
{
"ProjectId": "project2",
"TopicId": "topic2",
"PartnerId": 2,
"SubscriptionId": "sub2"
}
]
最终创建两个托管服务,一个使用第一组选项,另一个使用第二组。
我已经看到一些问题在寻找类似的东西,但我找不到与此完全一致的东西,所以我有点难过。有什么想法吗?
解决方案是 Dotnet 5。
也许你可以尝试只为对象创建一个 class 并让 PubSubSettings class 只为数组:
public class PubSubSettings
{
public PubSubObject[] PubSubs { get; set; }
}
public class PubSubObject
{
public string ProjectId { get; set; }
public string TopicId { get; set; }
public int PartnerId { get; set; }
public string SubscriptionId { get; set; }
}
然后在启动时class你应该使用Bind
获取数组的当前值来为每个PubSub
创建一个Worker
:
PubSubSettings settings = new PubSubSettings();
Configuration.GetSection(nameof(PubSubSettings)).Bind(settings);
...
foreach(PubSubObject item in settings.PubSubs)
{
services.AddHostedService<Worker>();
}
然后在PubSub
class中你需要搜索Array里面的PartnerId
。
或者您可以按照 Microsoft 文档中命名选项支持使用 IConfigureNamedOptions 部分中描述的方法:Options pattern in ASP.NET Core
因此,根据我所能找到的,没有任何开箱即用的方法。
但是,这可以使用 ActivatorUtilities
和 Configuration.Bind()
的组合手动完成。
private void CreateWorkers(IServiceCollection services, IConfigurationRoot configuration)
{
List<PubSubSettings> pubsubSettings = new();
configuration.Bind(nameof(PubSubSettings), pubsubSettings);
foreach (PubSubSettings setting in pubsubSettings)
{
services.AddSingleton<IHostedService>(s => ActivatorUtilities.CreateInstance<Worker>(s, ActivatorUtilities.CreateInstance<PubSub.PubSub>(s, setting)));
}
}
本质上,您可以使用Bind
从JSON 中获取配置对象。然后您可以使用 CreateInstance
.
Worker
以调用 AddHostedService
在这种情况下需要两次调用,一次为 worker 生成 PubSub
(我们在其中传递设置参数),另一次调用生成 Worker
本身。
ActivatorUtilities
本质上是注入对象所需的一切,除了您提供的参数。
我们需要使用 .AddSingleton<IHostedService>
因为 AddHostedService()
.