簡體   English   中英

.NET Core 使用配置綁定到帶數組的選項

[英].NET Core use Configuration to bind to Options with Array

使用 .NET Core Microsoft.Extensions.Configuration是否可以將 Configuration 綁定到包含數組的對象?

ConfigurationBinder有一個BindArray方法,所以我認為它會起作用。

但是當我嘗試時,我得到了一個例外:

System.NotSupportedException: ArrayConverter cannot convert from System.String.

這是我的精簡代碼:

public class Test
{
   private class ExampleOption
   { 
      public int[] Array {get;set;}
   }

   [Test]
   public void CanBindArray()
   {
       // ARRANGE
       var config =
            new ConfigurationBuilder()
            .AddInMemoryCollection(new List<KeyValuePair<string, string>>
            {
                new KeyValuePair<string, string>("Array", "[1,2,3]")
            })
            .Build();

        var exampleOption= new ExampleOption();

        // ACT
        config.Bind(complexOptions); // throws exception

       // ASSERT
       exampleOption.ShouldContain(1);
   }
}

錯誤在您的輸入定義中。 該示例將鍵“Array”設置為字符串值“[1,2,3]”(在基於 C# 的 InMemoryCollection 中),並假設它是解析的 JSON 樣式。 那是錯誤的。 它只是沒有被解析。

配置系統中數組值的編碼約定是通過用冒號和后面的索引重復鍵。 以下示例的工作方式與您打算做的一樣:

var config = new ConfigurationBuilder()
        .AddInMemoryCollection(new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("Array:0", "1"),
            new KeyValuePair<string, string>("Array:1", "2"),
            new KeyValuePair<string, string>("Array:2", "3")
        })
        .Build();

如果使用 JSON 文件(此處通過對 AddJsonFile 的附加調用),也會發生冒號鍵重復方案......

{
  "mySecondArray":  [1, 2, 3]
}

生成的組合配置將包含遵循與上述內存使用相同模式的鍵:

Count = 8
[0]: {[mySecondArray, ]}
[1]: {[mySecondArray:2, 3]}
[2]: {[mySecondArray:1, 2]}
[3]: {[mySecondArray:0, 1]}
[4]: {[Array, ]}
[5]: {[Array:2, 3]}
[6]: {[Array:1, 2]}
[7]: {[Array:0, 1]}

配置系統與 JSON/INI/XML/... 等存儲格式無關,本質上只是一個 string->string 字典,其中冒號在 key 內構成層次結構。

然后綁定能夠通過約定解釋一些層次結構,因此也綁定數組、集合、對象和字典。 有趣的是,對於數組,它並不關心冒號后面的數字,而只是迭代配置部分的子項(此處為“數組”)並獲取子項的值。 分揀再次孩子,需要的數量考慮,而且排序字符串作為第二個選項(OrdinalIgnoreCase)。

隨着最近對 C# 語言的添加,使用更新的語法更清晰:

var config = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string>
    {
        { "Array:0", "1" },
        { "Array:1", "2" },
        { "Array:2", "3" },
    })
    .Build();

您可以使用ConfigureServices方法中的代碼配置ExampleOption

 public void ConfigureServices(IServiceCollection services)
 {
      services.Configure<ExampleOption>(myOptions =>
      {
          myOptions.Array = new int[] { 1, 2, 3 };
      });
 }

或者如果你想使用 json 配置文件

appsettings.json

{
  "ExampleOption": {
     "Array": [1,2,3]
  }
}

ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ExampleOption>(Configuration.GetSection("ExampleOption"));
}

暫無
暫無

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

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