Joh*_*nny 0 c# configuration app-config
我想在稍微不同的场景中实现Craig Andera的自定义XML配置处理程序.我想要做的是读入任意长度的自定义对象列表,定义如下:
public class TextFileInfo
{
public string Name { get; set; }
public string TextFilePath { get; set; }
public string XmlFilePath { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我设法为一个自定义对象复制了Craig的解决方案,但如果我想要几个呢?
Craig的反序列化代码是:
public class XmlSerializerSectionHandler : IConfigurationSectionHandler
{
public object Create(object parent, object configContext, XmlNode section)
{
XPathNavigator nav = section.CreateNavigator();
string typename = (string)nav.Evaluate("string(@type)");
Type t = Type.GetType(typename);
XmlSerializer ser = new XmlSerializer(t);
return ser.Deserialize(new XmlNodeReader(section));
}
}
Run Code Online (Sandbox Code Playgroud)
如果可以的话,我想我能做到这一点
Type t = Type.GetType("System.Collections.Generic.List<TextFileInfo>")
Run Code Online (Sandbox Code Playgroud)
工作,但它抛出
Could not load type 'System.Collections.Generic.List<Test1.TextFileInfo>' from assembly 'Test1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Run Code Online (Sandbox Code Playgroud)
我不认为这会在那种情况下起作用.Craig的解决方案适用于简单的对象图,但集合有点棘手.列表被序列化为数组,因此将示例放入序列化List中就像:
<ArrayOfTextFileInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlsns:xsd="http://www.w3.org/2001/XMLSchema>
<TextFileInfo>
<Name>My Text File</Name>
<TextFilePath>C:\MyTextFile.txt</TextFilePath>
<XmlFilePath>C:\MyXmlFile.xml</XmlFilePath>
</TextFileInfo>
</ArrayOfTextFileInfo>
Run Code Online (Sandbox Code Playgroud)
现在,我猜你可以将它放在配置中,只要配置部分命名为"ArrayOfTextFileInfo".不完全那么友好.我认为您应该做的是使用标准配置类来构建它:
public class TextFileConfigurationElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name {
get { return (string)this["name"]; }
set { this["name"] = value; }
}
[ConfigurationProperty("textFilePath")]
public string TextFilePath {
get { return (string)this["textFilePath"]; }
set { this["textFilePath"] = value; }
}
[ConfigurationProperty("xmlFilePath")]
public string XmlFilePath {
get { return (string)this["xmlFilePath"]; }
set { this["xmlFilePath"] = value; }
}
}
[ConfigurationCollection(typeof(TextFileConfigurationElement))]
public class TextFileConfigurationElementCollection : ConfigurationElementCollection
{
protected override void CreateNewElement() {
return new TextFileConfigurationElement();
}
protected override object GetElementKey(ConfigurationElement element) {
return ((TextFileConfigurationElement)element).Name;
}
}
public class TextFilesConfigurationSection : ConfigurationSection
{
[ConfigurationProperty("files")]
public TextFileConfigurationElementCollection Files {
get { return (TextFileConfigurationElementCollection)this["files"]; }
set { this["files"] = value; }
}
public static TextFilesConfigurationSection GetInstance() {
return ConfigurationManager.GetSection("textFiles") as TextFilesConfigurationSection;
}
}
Run Code Online (Sandbox Code Playgroud)
一旦注册了配置部分:
<configSections>
<add name="textFiles" type="...{type here}..." />
</configSections>
Run Code Online (Sandbox Code Playgroud)
您可以添加配置:
<textFiles>
<files>
<add name="File01" textFilePath="C:\File01.txt" xmlTextFile="C:\File01.xml" />
</files>
</textFiles>
Run Code Online (Sandbox Code Playgroud)
在代码中使用它:
public List<TextFileInfo> GetFiles() {
var list = new List<TextFileInfo>();
var config = TextFileConfigurationSection.GetInstance();
if (config == null)
return list;
foreach (TextFileConfigurationElement fileConfig in config.Files) {
list.Add(new TextFileInfo
{
Name = fileConfig.Name,
TextFilePath = fileConfig.TextFilePath,
XmlFilePath = fileConfig.XmlFilePath
});
}
return list;
}
Run Code Online (Sandbox Code Playgroud)
这个:
Type t = Type.GetType("System.Collections.Generic.List<TextFileInfo>")
Run Code Online (Sandbox Code Playgroud)
由于几个原因无法工作,你没有完全限定TextFileInfo类型(需要一个命名空间),你的泛型类型的定义是错误的(我可以看到为什么你没有这样指定),它应该是这样的:
Type t = Type.GetType("System.Collections.Generic.List`1[MyNamespace.TextFileInfo]");
Run Code Online (Sandbox Code Playgroud)
希望有所帮助!