使用.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);
}
}
答案 0 :(得分:18)
错误在您的输入定义中。该示例设置了一个键&#34;数组&#34;字符串值为&#34; [1,2,3]&#34; (在基于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 / ...等存储格式无关,基本上只是一个字符串 - >字符串字典,冒号在密钥中构成层次结构。 / p>
然后,Bind能够通过约定来解释某些层次结构,因此也会绑定数组,集合,对象和字典。有趣的是,对于数组,它并不关心冒号后面的数字,只关注iterate配置部分的子节点(这里是#34;数组&#34;)并取值子节点的值。孩子的sorting再次考虑数字,但也将字符串排序为第二个选项(OrdinalIgnoreCase)。
答案 1 :(得分:5)
您可以使用ExampleOption
方法:
ConfigureServices
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"));
}
答案 2 :(得分:1)
随着C#语言的最新添加,使用更新的语法更干净
var config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "Array:0", "1" },
{ "Array:1", "2" },
{ "Array:2", "3" },
})
.Build();