如何将派生 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
,它应该包含 GuiConfiguration
和 LogLineCount
属性.
这是因为我不想在每个应用程序的应用程序日志中实施。
然后我有一个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);
}
}
我希望它能帮助其他人:-)
我有 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
,它应该包含 GuiConfiguration
和 LogLineCount
属性.
这是因为我不想在每个应用程序的应用程序日志中实施。
然后我有一个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);
}
}
我希望它能帮助其他人:-)