问题是我有一个可以使用我的模型更新的配置,我部署新的更新并且用户不会获得更新的配置文件,因此它将导致空引用异常等。现在我只需设置默认值或使用 new( )使其至少与最新的配置值相似,但这太糟糕了,我需要始终支持它,如果我或其他人甚至忘记合并空属性怎么办?
我有 3 个不同的配置文件(YAML、XML、JSON),但只有一个模型。 我希望它将所有空属性、数组的数组、默认配置中不存在的数组项合并到现有配置、属性的属性等中,但是我想保存反序列化配置中的所有现有内容。
我的模特:
[Serializable]
public class GuardSettings
{
public GuardSettings()
{
}
public UnturnedGuardOptions UnturnedGuardOptions { get; set; }
public UnturnedIntegrityVault UnturnedIntegrityVault { get; set; }
public LocalTimeOptions LocalTimeOptions { get; set; }
[YamlIgnore, XmlIgnore] public VanillaOptions VanillaOptions { get; set; }
public LogReport LogReport { get; set; }
public DiscordWebhookLaunch DiscordWebhookLaunch { get; set; }
public DiscordWebhookReject DiscordWebhookReject { get; set; }
public DiscordWebhookAccept DiscordWebhookAccept { get; set; }
public DiscordWebhookCancel DiscordWebhookCancel { get; set; }
public DiscordWebhookReport DiscordWebhookReport { get; set; }
public DiscordWebhookBans DiscordWebhookBans { get; set; }
public DiscordWebhookUnbans DiscordWebhookUnbans { get; set; }
public DatabaseOptions DatabaseOptions { get; set; }
public UnturnedPanelIntegration UnturnedPanelIntegration { get; set; }
public BanOptions BanOptions { get; set; }
public PlayerWhitelist PlayerWhitelist { get; set; }
public HWIDHistory HWIDHistory { get; set; }
[YamlMember(Alias = "tpsOptions")] public TPSOptions TPSOptions { get; set; }
public FeaturesOptions FeaturesOptions { get; set; }
public Feature[] Features { get; set; }
}
[Serializable]
public class Feature
{
public Feature()
{
}
public string Name { get; set; } = string.Empty;
public bool Enabled { get; set; }
public Argument[] Arguments { get; set; } = Array.Empty<Argument>();
}
[Serializable]
public class Argument
{
public Argument()
{
}
public string? Name { get; set; }
public object? Value { get; set; }
}
这就是我的看法,我的默认设置只是使用我的自定义工厂来配置默认配置的所有属性(以正确的方式),并且现有设置是来自文件(YAML、XML 或 JSON)的反序列化配置。
private static GuardSettings Merge(GuardSettings defaultSettings, GuardSettings existingSettings)
之后,我想序列化合并的配置以更新配置,以便用户可以更改最新的属性并了解配置中的更改!
我尝试使用Reflection和AutoMapper,但没有成功。
我通常使用的方法是初始化可选属性:
public class MyConfiguration{
[JsonRequiredAttribute]
public string MyRequiredProperty {get;set;} // Required property, no default value needed.
public long MyOptionalProperty {get;set;} = 42; // Optional property, default value needed
}
许多序列化库将替换文件中的
MyOptionalProperty
(如果存在),如果不存在则保留默认值。但请检查您的特定库是否以这种方式工作。通常有某种类型的属性来将属性标记为必需或非必需,因此您可以相当快速地检查所有可选属性是否具有默认值。
如果配置布局发生较大更改,创建新类型可能会很有用,因此您可以反序列化旧类型并手动将其转换为新布局。如果您使用“DTO”,即类型only用于序列化,这会更容易。
反序列化对象,然后将其与默认对象合并似乎有问题。您将需要相当多的复杂反射,并且您将无法处理值类型,即您不知道零是否代表缺失值,或者只是代表设置为零的值。