为什么这个自定义配置提供程序不正确地绑定数组元素?
Why does this custom configuration provider incorrectly bind array elements?
我正准备在 .NET Core 2.2 中编写自定义配置提供程序。我的自定义配置提供程序扩展了 ConfigurationProvider class。它将 Data 属性 设置为表示包含字符串数组的对象的字典。当我尝试将构建的配置绑定到 class 时,数组值最终为空。当我将同一个字典与 InMemoryCollection 提供程序一起使用时,数组值被正确绑定。
public class TestConfigProvider : ConfigurationProvider
{
public override void Load()
{
Data = new Dictionary<string, string>
{
{"array:entries:0", "value0"},
{"array:entries:1", "value1"}
};
}
}
public class TestConfigSource : IConfigurationSource
{
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new TestConfigProvider();
}
}
public static class TestConfigExtensions
{
public static IConfigurationBuilder AddCustomConfig(this IConfigurationBuilder builder)
{
return builder.Add(new TestConfigSource());
}
}
public class ArrayExample
{
public string[] Entries { get; set; }
}
public class Program
{
public static Dictionary<string, string> _data = new Dictionary<string, string>
{
{"array:entries:0", "value0"},
{"array:entries:1", "value1"}
};
static void Main(string[] args)
{
IConfiguration config1 = new ConfigurationBuilder()
.AddCustomConfig()
.Build();
IConfiguration config2 = new ConfigurationBuilder()
.AddInMemoryCollection(_data)
.Build();
var test1 = config1.GetSection("array").Get<ArrayExample>();
var test2 = config2.GetSection("array").Get<ArrayExample>();
Console.WriteLine(JsonConvert.SerializeObject(test1)); // {"Entries":[null,null,null,null,null]}
Console.WriteLine(JsonConvert.SerializeObject(test2)); // {"Entries":["value0","value1","value2","value4","value5"]}
}
}
我希望两个配置都能绑定数组值。
我可以使用配置对象上的索引运算符提取各个值。
查看 MemoryConfigurationProvider
的来源并查看它们如何填充提供的初始数据后
public MemoryConfigurationProvider(MemoryConfigurationSource source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
_source = source;
if (_source.InitialData != null)
{
foreach (var pair in _source.InitialData)
{
Data.Add(pair.Key, pair.Value);
}
}
}
通过填充 Data
而不是替换整个对象。
我在 TestConfigProvider
中做了同样的事情
public class TestConfigProvider : ConfigurationProvider {
public override void Load() {
var initialData = new Dictionary<string, string>
{
{"array:entries:0", "value0"},
{"array:entries:1", "value1"}
};
foreach (var pair in initialData) {
Data.Add(pair.Key, pair.Value);
}
}
}
并获得了与使用内存中提供程序类似的结果,通过在测试时填充数组值来实现所需的绑定行为
[TestClass]
public class CustomConfigurationTests {
public static Dictionary<string, string> _data = new Dictionary<string, string>
{
{"array:entries:0", "value0"},
{"array:entries:1", "value1"}
};
[TestMethod]
public void Should_Bind_Array() {
//Arrange
IConfiguration config1 = new ConfigurationBuilder()
.AddCustomConfig()
.Build();
IConfiguration config2 = new ConfigurationBuilder()
.AddInMemoryCollection(_data)
.Build();
//Act
var test1 = config1.GetSection("array").Get<ArrayExample>();
var test2 = config2.GetSection("array").Get<ArrayExample>();
//Assert
test1.Entries.Should().BeEquivalentTo(test2.Entries);
}
}
我正准备在 .NET Core 2.2 中编写自定义配置提供程序。我的自定义配置提供程序扩展了 ConfigurationProvider class。它将 Data 属性 设置为表示包含字符串数组的对象的字典。当我尝试将构建的配置绑定到 class 时,数组值最终为空。当我将同一个字典与 InMemoryCollection 提供程序一起使用时,数组值被正确绑定。
public class TestConfigProvider : ConfigurationProvider
{
public override void Load()
{
Data = new Dictionary<string, string>
{
{"array:entries:0", "value0"},
{"array:entries:1", "value1"}
};
}
}
public class TestConfigSource : IConfigurationSource
{
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new TestConfigProvider();
}
}
public static class TestConfigExtensions
{
public static IConfigurationBuilder AddCustomConfig(this IConfigurationBuilder builder)
{
return builder.Add(new TestConfigSource());
}
}
public class ArrayExample
{
public string[] Entries { get; set; }
}
public class Program
{
public static Dictionary<string, string> _data = new Dictionary<string, string>
{
{"array:entries:0", "value0"},
{"array:entries:1", "value1"}
};
static void Main(string[] args)
{
IConfiguration config1 = new ConfigurationBuilder()
.AddCustomConfig()
.Build();
IConfiguration config2 = new ConfigurationBuilder()
.AddInMemoryCollection(_data)
.Build();
var test1 = config1.GetSection("array").Get<ArrayExample>();
var test2 = config2.GetSection("array").Get<ArrayExample>();
Console.WriteLine(JsonConvert.SerializeObject(test1)); // {"Entries":[null,null,null,null,null]}
Console.WriteLine(JsonConvert.SerializeObject(test2)); // {"Entries":["value0","value1","value2","value4","value5"]}
}
}
我希望两个配置都能绑定数组值。
我可以使用配置对象上的索引运算符提取各个值。
查看 MemoryConfigurationProvider
的来源并查看它们如何填充提供的初始数据后
public MemoryConfigurationProvider(MemoryConfigurationSource source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
_source = source;
if (_source.InitialData != null)
{
foreach (var pair in _source.InitialData)
{
Data.Add(pair.Key, pair.Value);
}
}
}
通过填充 Data
而不是替换整个对象。
我在 TestConfigProvider
public class TestConfigProvider : ConfigurationProvider {
public override void Load() {
var initialData = new Dictionary<string, string>
{
{"array:entries:0", "value0"},
{"array:entries:1", "value1"}
};
foreach (var pair in initialData) {
Data.Add(pair.Key, pair.Value);
}
}
}
并获得了与使用内存中提供程序类似的结果,通过在测试时填充数组值来实现所需的绑定行为
[TestClass]
public class CustomConfigurationTests {
public static Dictionary<string, string> _data = new Dictionary<string, string>
{
{"array:entries:0", "value0"},
{"array:entries:1", "value1"}
};
[TestMethod]
public void Should_Bind_Array() {
//Arrange
IConfiguration config1 = new ConfigurationBuilder()
.AddCustomConfig()
.Build();
IConfiguration config2 = new ConfigurationBuilder()
.AddInMemoryCollection(_data)
.Build();
//Act
var test1 = config1.GetSection("array").Get<ArrayExample>();
var test2 = config2.GetSection("array").Get<ArrayExample>();
//Assert
test1.Entries.Should().BeEquivalentTo(test2.Entries);
}
}