如何使用其他派生类作为属性反序列化派生类

时间:2019-09-20 09:26:04

标签: c# xml inheritance deserialization abstract

我有2个项目。一个是WPF应用程序,第二个是我的“工具箱”,具有预定义的WPF控件,XML反序列化和一些基本配置类。

在我的工具箱中,我有一个ConfigurationBase类:

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

这是GuiConfigurationBase

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

我的工具包包含应用程序内日志消息的预定义视图。因此,我的LogViewModel构造函数需要一个ConfigurationBase,其中应包含具有GuiConfiguration属性的LogLineCount

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

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

我还需要扩展GuiConfigurationBase,所以我有一个叫GuiConfiguration的类,它是从GuiConfigurationBase派生的。

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

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

我还使用XmlSerializer对XML文件进行反序列化。我需要填写我的两个派生类。

请问我该如何实现?

我尝试了一些对基类的抽象,但是没有成功。

谢谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。 必须使用XmlAttributeOverrides

因为我有两个项目,所以我不得不使用反射来检索从GuiConfigurationBase派生的类。 (我对项目一无所知,在其中引用了我的工具箱项目)

然后为每个类添加新的XmlElementAttribute(在我的情况下,使用Linq First()方法就足够了)-这应该与XmlIncludeAttribute(Type)相同

最后为XmlAttributeOverrides类的属性ConfigurationBase添加GuiConfiguration

这是我的反序列化方法:

 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);
        }
    }

我希望它会对其他人有所帮助:-)