.NET Core 使用配置绑定到带有数组的选项
.NET Core use Configuration to bind to Options with Array
使用 .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);
}
}
您可以使用 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"));
}
错误在您的输入定义中。该示例将键 "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 能够通过约定 解释一些层次结构,因此也可以绑定数组、集合、对象和字典。有趣的是,对于数组,它不关心冒号后面的数字,而只关心子项的 iterate the children of the configuration section (here "Array") and take the values of the children. The sorting,将数字考虑在内,但还将字符串排序为第二个选项(OrdinalIgnoreCase)。
随着最近对 C# 语言的补充,使用更新的语法更加简洁:
var config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "Array:0", "1" },
{ "Array:1", "2" },
{ "Array:2", "3" },
})
.Build();
或者您可以使用其他新语法
var config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
["Array:0"] = "1",
["Array:1"] = "2",
["Array:2"] = "3",
})
.Build();
使用 .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);
}
}
您可以使用 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"));
}
错误在您的输入定义中。该示例将键 "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 能够通过约定 解释一些层次结构,因此也可以绑定数组、集合、对象和字典。有趣的是,对于数组,它不关心冒号后面的数字,而只关心子项的 iterate the children of the configuration section (here "Array") and take the values of the children. The sorting,将数字考虑在内,但还将字符串排序为第二个选项(OrdinalIgnoreCase)。
随着最近对 C# 语言的补充,使用更新的语法更加简洁:
var config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "Array:0", "1" },
{ "Array:1", "2" },
{ "Array:2", "3" },
})
.Build();
或者您可以使用其他新语法
var config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
["Array:0"] = "1",
["Array:1"] = "2",
["Array:2"] = "3",
})
.Build();