the*_*ric 10 .net-core asp.net-core
我正在进行.NET Core应用程序的集成测试,并希望使用一些测试配置.我的配置是一个POCO类,通过appsettings.json然后通过消耗配置IOptions<T>.在我的测试中,我想使用该类的实例.
这是代码:
var mySettings = GetTestSettings(); // factory method returning POCO class
var configurationBuilder = new ConfigurationBuilder();
// I am looking for something like
configurationBuilder.AddInMemoryObject("Settings", mySettings);
// does not work, result is just string
configurationBuilder.AddInMemoryCollection("Settings",
JsonConvert.SerializeObject(mySettings));
// requires filename
configurationBuilder.AddJsonFile("filename.json");
Run Code Online (Sandbox Code Playgroud)
将POCO提供给配置的最简单方法是什么?
AddInMemoryCollection获取KeyValuePair键设置键的位置的集合,值是其值.这个来自问题的电话
configurationBuilder.AddInMemoryCollection("Settings", JsonConvert.SerializeObject(mySettings));
Run Code Online (Sandbox Code Playgroud)
实际上将"设置"作为键和整个JSON作为一个设置值传递,这预期不起作用.
但总体方法是正确的,你应该使用AddInMemoryCollection扩展调用.在传递给此调用的集合中,设置键是配置中的完整路径,由冒号分隔.假设您有以下设置POCO:
public class SomeSettings
{
public string SomeKey1 { get; set; }
public int SomeKey2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
它是从以下JSON加载的
{
"SomeSettings": {
"SomeKey1": "SomeData",
"SomeKey2": 123
}
}
Run Code Online (Sandbox Code Playgroud)
钥匙将是SomeSettings:SomeKey1和SomeSettings:SomeKey2.
然后,您可以通过以下AddInMemoryCollection调用添加此类配置:
configurationBuilder.AddInMemoryCollection(new Dictionary<string, string>
{
{ "SomeSettings:SomeKey1", "SomeData" },
{ "SomeSettings:SomeKey2", 123 },
});
Run Code Online (Sandbox Code Playgroud)
现在,如果要通过一次调用添加设置POCO,则可以编写简单的扩展方法,该方法将使用反射枚举设置类属性,并返回属性名称和值的键 - 值对的集合.
这是一个示例:
public static class ObjectExtensions
{
public static IEnumerable<KeyValuePair<string, string>> ToKeyValuePairs(this Object settings, string settingsRoot)
{
foreach (var property in settings.GetType().GetProperties())
{
yield return new KeyValuePair<string, string>($"{settingsRoot}:{property.Name}", property.GetValue(settings).ToString());
}
}
}
public static class ConfigurationBuilderExtensions
{
public static void AddInMemoryObject(this ConfigurationBuilder configurationBuilder, object settings, string settingsRoot)
{
configurationBuilder.AddInMemoryCollection(settings.ToKeyValuePairs(settingsRoot));
}
}
Run Code Online (Sandbox Code Playgroud)
在测试中:
var configurationBuilder = new ConfigurationBuilder();
var mySettings = GetTestSettings();
configurationBuilder.AddInMemoryObject(mySettings, "Settings");
Run Code Online (Sandbox Code Playgroud)
这种简单的ObjectExtensions.ToKeyValuePairs扩展方法适用于SomeSettings上面的普通POCO .但是,如果某些属性也是这样的对象,它将无法工作:
public class InnerSettings
{
public string SomeKey { get; set; }
}
public class OuterSettings
{
public InnerSettings InnerSettings { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
但是我相信你有一个想法,如果需要可以进行必要的调整.
我最终得到以下结果:
configurationBuilder.AddInMemoryCollection(ToDictionary(GetTestSettings()));
private static IEnumerable<KeyValuePair<string, string>> ToDictionary(object o) =>
AddPropsToDic(JObject.FromObject(o), new Dictionary<string, string>(), "Settings");
private static Dictionary<string, string> AddPropsToDic(JObject jo, Dictionary<string, string> dic, string prefix)
{
jo.Properties()
.Aggregate(dic, (d, jt) =>
{
var value = jt.Value;
var key = $"{prefix}:{jt.Name}";
if (value.HasValues)
return AddPropsToDic((JObject) jt.Value, dic, key);
dic.Add(key, value.ToString());
return dic;
});
return dic;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
772 次 |
| 最近记录: |