web-dev-qa-db-ja.com

.NET Coreは構成を使用して配列を含むオプションにバインドします

.NET Coreの使用Microsoft.Extensions.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);
   }
}
13
Philip Pittle

エラーは入力定義にあります。このサンプルでは、​​キー「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/...のようなストレージフォーマットに依存せず、本質的に、コロンをキー

その後、Bindはconventionsによって階層の一部を解釈できるため、配列、コレクション、オブジェクト、および辞書もバインドします。興味深いことに、配列の場合は、コロンの後ろの数字は気にせず、 iterate 構成セクションの子(ここでは「配列」)だけを扱い、子の値を取ります。子の sorting は、数値を考慮に入れますが、2番目のオプション(OrdinalIgnoreCase)として文字列をソートします。

19
Thomas

ExampleOptionメソッドでConfigureServiceswithコードを設定できます:

 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"));
}
5
adem caglin

C#言語への最近の追加により、新しい構文を使用する方がクリーンです

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

1
codevision