config.yaml:
App1:
settings:
redirectUrl: http://www.test.com
App2:
settings:
redirectUrl:
test: http://www.test.com
prod: http://www.prod.com
C# 对象
public class Config
{
public Dictionary<string, App> Apps { get; set; }
}
public class App
{
public Dictionary<string, Setting> Settings { get; set; }
}
public class Setting
{
public string Test {get;set;}
public string Prod {get;set;}
}
预期结果:
对于App1
,test
和prod
都是相同的http://www.test.com
对于 App2
,test
为 http://www.test.com
,prod
为 http://www.prod.com
我做了很多研究,但不知道如何通过使用自定义反序列化器来实现这一点。 请帮忙..
最佳答案
您可以使您的 Settings
类实现 IYamlConvertible
。该接口(interface)允许您控制序列化过程。一个可能的实现可能是:
public class SettingsBase
{
public string Test { get; set; }
public string Prod { get; set; }
}
public class Setting : SettingsBase, IYamlConvertible
{
public void Read(IParser parser, Type type, ObjectDeserializer nestedObjectDeserializer)
{
var scalar = parser.Allow<Scalar>();
if (scalar != null)
{
Test = Prod = scalar.Value;
}
else
{
var values = (SettingsBase)nestedObjectDeserializer(typeof(SettingsBase));
this.Test = values.Test;
this.Prod = values.Prod;
}
}
public void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
{
if (Test == Prod)
{
nestedObjectSerializer(Test);
}
else
{
nestedObjectSerializer(new SettingsBase { Test = this.Test, Prod = this.Prod });
}
}
}
这里,我使用基类 (SettingsBase
) 作为一种轻松(反)序列化属性的方法,但也可以使用另一种策略。基本上,Read
方法检查当前标记是否是标量。如果是这样,它就使用它的值。否则,它会反序列化为 SettingsBase
。 Write
方法执行相反的操作。
关于YamlDotNet:如何自定义反序列化器以处理具有不同类型值的相同键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51435425/