我正在制作一个程序,它将加载基于 xml 的配置文件(虽然不是 app.config)。
在这个配置文件中,我将指定必须由程序实例化和配置的类型。
这是我如何设想的一个例子:
<?xml version="1.0"?>
<configuration>
<types>
<type assembly="SomeAssembly.dll" class="SomeAssembly.SomeClass">
<type-configuration>
<address>192.168.0.1</address>
<port>80</port>
</type-configuration>
</type>
</types>
</configuration>
那个最里面的元素就是问题所在<type-configuration>
。里面的元素将取决于 所需的特定配置SomeAssembly.SomeClass
,并且根本不为程序“所知”。
通过添加新类型,该部分可能如下所示:
<type assembly="SomeAssembly.dll" class="SomeAssembly.SomeClass">
<type-configuration>
<address>192.168.0.1</address>
<port>80</port>
</type-configuration>
</type>
<type assembly="SomeOtherAssembly.dll" class="SomeOtherAssembly.SomeOtherClass">
<type-configuration>
<url>http://www.domain.com/path/to/webpage</url>
<authentication-token>1234567890ABC</authentication-token>
</type-configuration>
</type>
有什么方法可以将上述 XML 文件反序列化为强类型对象,并且仍然随身携带该子 XML 部分,以便类型本身可以将其反序列化为自己的对象?
IE。我的程序的配置类可能是这样的:
[XmlType("configuration")]
public class Configuration
{
[XmlElement("types")]
public Collection<SubType> Types
{
...
}
}
[XmlType("type")]
public class SubType
{
[XmlElement("configuration")]
public ??? Configuration { get; set; }
}
我如何声明该SubType.Configuration
财产?这甚至可能吗?
请注意,最终,该属性中的任何数据都将提供给配置文件中指定类型的实例化对象。我还没有写那部分,所以不管怎样都行,真的,
这是一个完整的LINQPad程序,它演示了我想要什么,以及我已经走了多远:
void Main()
{
const string xml = @"<?xml version=""1.0""?>
<configuration>
<types>
<type assembly=""SomeAssembly.dll"" class=""SomeAssembly.SomeClass"">
<type-configuration>
<address>192.168.0.1</address>
<port>80</port>
</type-configuration>
</type>
<type assembly=""SomeOtherAssembly.dll"" class=""SomeOtherAssembly.SomeOtherClass"">
<type-configuration>
<url>http://www.domain.com/path/to/webpage</url>
<authentication-token>1234567890ABC</authentication-token>
</type-configuration>
</type>
</types>
</configuration>";
var serializer = new XmlSerializer(typeof(Configuration));
using (var reader = new StringReader(xml))
{
var configuration = (Configuration)serializer.Deserialize(reader);
configuration.Dump();
}
}
[XmlType("configuration")]
public class Configuration
{
private readonly Collection<SubType> _Types = new Collection<SubType>();
[XmlArray("types")]
public Collection<SubType> Types
{
get
{
return _Types;
}
}
}
[XmlType("type")]
public class SubType
{
private readonly Collection<XmlNode> _Configuration = new Collection<XmlNode>();
[XmlAttribute("assembly")]
public string AssemblyName { get; set; }
[XmlAttribute("class")]
public string ClassName { get; set; }
[XmlElement("type-configuration")]
public Collection<XmlNode> Configuration
{
get
{
return _Configuration;
}
}
}
这将转储出两个SubType
对象,但该Configuration
属性仅包含该<type-configuration>...</type-configuration>
部分的第一个子元素。将属性类型更改为string
只给我最里面的文本,即。ip 地址或 url,并将其更改为XmlDocument
与 for 相同XmlNode
。