如何将派生 class 与其他派生 class 反序列化为 属性

How to deserialize derived class with other derived class as property

我有 2 个项目。一个是 WPF 应用程序,第二个是我的 "toolkit",具有预定义的 WPF 控件、XML 反序列化和一些基本配置 classes.

在我的工具包中我有一个 ConfigurationBase class:

public class ConfigurationBase : XmlDeserializeConfigSectionHandler
{
      public GuiConfigurationBase GuiConfiguration { get; set; }
}

这是GuiConfigurationBase

public class GuiConfigurationBase
{
    public int LogLineCount { get; set; }
}

我的工具包包含应用日志消息的预定义视图。所以我的 LogViewModel 构造函数需要一个 ConfigurationBase ,它应该包含 GuiConfigurationLogLineCount 属性.

这是因为我不想在每个应用程序的应用程序日志中实施。

然后我有一个WPF项目。它包含从 ConfigurationBase 派生的 class Config。它扩展了一些其他不重要的道具。

我还需要扩展 GuiConfigurationBase 所以我将 class 称为 GuiConfiguration 派生自 GuiConfigurationBase.

public class Config : ConfigurationBase
{
    public string AppName { get; set; }
}

public class GuiConfiguration : GuiConfigurationBase
{
    public int TextSize { get; set; }
}

我还使用 XmlSerializer 反序列化我的 XML 文件。我需要填写我派生的两个 classes.

请问我该如何实现?

我尝试对基础 classes 进行一些抽象,但没有成功。

感谢您的任何建议。

我找到了解决办法。 有必要使用XmlAttributeOverrides

因为我有两个项目,所以我必须使用反射来检索从 GuiConfigurationBase 派生的 classes。 (我对我的工具包项目引用的项目一无所知)

然后为每个 class 添加新的 XmlElementAttribute(在我的例子中,使用 Linq First() 方法就足够了)- 这应该与 XmlIncludeAttribute 相同(类型)

最后为 ConfigurationBase class 的 属性 GuiConfiguration

添加 XmlAttributeOverrides

这是我的反序列化方法:

 public T Deserialize<T>(string input) where T : class
    {
        //Init attrbibutee overrides
        XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
        XmlAttributes attrs = new XmlAttributes();

        //Load all types which derive from GuiConfiguration base
        var guiConfTypes = (from lAssembly in AppDomain.CurrentDomain.GetAssemblies()
                            from lType in lAssembly.GetTypes()
                            where typeof(GuiConfigurationBase).IsAssignableFrom(lType) && lType != typeof(GuiConfigurationBase)
                            select lType).ToArray();


        //All classes which derive from GuiConfigurationBase
        foreach (var guiConf in guiConfTypes)
        {
            XmlElementAttribute attr = new XmlElementAttribute
            {
                ElementName = guiConf.Name,
                Type = guiConf
            };

            attrs.XmlElements.Add(attr);
        }

        //Add Attribute overrides for ConfigurationBase class's property GuiConfiguration
        attrOverrides.Add(typeof(ConfigurationBase), nameof(ConfigurationBase.GuiConfiguration), attrs);

        XmlSerializer ser = new XmlSerializer(typeof(T), attrOverrides);

        using (StringReader sr = new StringReader(input))
        {
            return (T)ser.Deserialize(sr);
        }
    }

我希望它能帮助其他人:-)