簡體   English   中英

基於配置文件的具有不同參數的類的多個實例

[英]Multiple instances of class with different parameters based on configuration file

所以我有一個簡單的配置類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 中配置了其中一個,但現在我希望能夠處理任意數量的它們。

我有另一個類PubSub ,我通常將IOptions<PubSubSettings>注入其中。 這反過來又被注入到我的Worker類中。

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。

因此,根據我所能找到的,沒有辦法開箱即用。

但是,這可以使用ActivatorUtilitiesConfiguration.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()檢查欺騙的方式。

也許你可以嘗試只為對象創建一個類,讓 PubSubSettings 類只為數組:

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; }
}

然后在啟動類中,您應該使用Bind獲取數組的當前值,以便為每個PubSub創建一個Worker

PubSubSettings settings = new PubSubSettings();
Configuration.GetSection(nameof(PubSubSettings)).Bind(settings);
...
foreach(PubSubObject item in settings.PubSubs)
{
   services.AddHostedService<Worker>();
}

然后在PubSub類中,您需要在 Array 中搜索PartnerId

或者,您可以遵循 Microsoft 文檔中使用 IConfigureNamedOptions 的命名選項支持部分中描述的方法: ASP.NET Core 中的選項模式

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM