简体   繁体   English

如何以编程方式加载配置文件

[英]How to Load Config File Programmatically

Suppose I have a Custom Config File which corresponds to a Custom-defined ConfigurationSection and Config elements. 假设我有一个自定义配置文件,它对应于自定义的ConfigurationSection和Config元素。 These config classes are stored in a library. 这些配置类存储在库中。

Config File looks like this Config File看起来像这样

<?xml version="1.0" encoding="utf-8" ?>
<Schoool Name="RT">
  <Student></Student>
</Schoool>

How can I programmatically load and use this config file from Code? 如何以编程方式从代码中加载和使用此配置文件?

I don't want to use raw XML handling, but leverage the config classes already defined. 我不想使用原始XML处理,而是利用已经定义的配置类。

You'll have to adapt it for your requirements, but here's the code I use in one of my projects to do just that: 你必须根据你的要求调整它,但这是我在我的一个项目中使用的代码:

var fileMap = new ConfigurationFileMap("pathtoconfigfile");
var configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
var sectionGroup = configuration.GetSectionGroup("applicationSettings"); // This is the section group name, change to your needs
var section = (ClientSettingsSection)sectionGroup.Sections.Get("MyTarget.Namespace.Properties.Settings"); // This is the section name, change to your needs
var setting = section.Settings.Get("SettingName"); // This is the setting name, change to your needs
return setting.Value.ValueXml.InnerText;

Note that I'm reading a valid .net config file. 请注意,我正在阅读有效的.net配置文件。 I'm using this code to read the config file of an EXE from a DLL. 我正在使用此代码从DLL中读取EXE的配置文件。 I'm not sure if this works with the example config file you gave in your question, but it should be a good start. 我不确定这是否适用于您在问题中提供的示例配置文件,但它应该是一个良好的开端。

Check out Jon Rista's three-part series on .NET 2.0 configuration up on CodeProject. 在CodeProject上查看Jon Rista关于.NET 2.0配置的三部分系列。

Highly recommended, well written and extremely helpful! 强烈推荐,写得很好,非常有帮助!

You can't really load any XML fragment - what you can load is a complete, separate config file that looks and feels like app.config. 您无法真正加载任何XML片段 - 您可以加载的是一个完整,独立的配置文件,其外观和感觉就像是app.config。

If you want to create and design your own custom configuration sections, you should definitely also check out the Configuration Section Designer on CodePlex - a Visual Studio addin that allows you to visually design the config sections and have all the necessary plumbing code generated for you. 如果您想创建和设计自己的自定义配置部分,您还应该查看CodePlex上的配置部分设计器 - 一个Visual Studio插件,它允许您直观地设计配置部分并为您生成所有必需的管道代码。

The configSource attribute allows you to move any configuration element into a seperate file. configSource属性允许您将任何配置元素移动到单独的文件中。 In your main app.config you would do something like this: 在你的主app.config中你会做这样的事情:

<configuration>
  <configSections>
    <add name="schools" type="..." />
  </configSections>

  <schools configSource="schools.config />
</configuration>

Following code will allow you to load content from XML into objects. 以下代码将允许您将XML中的内容加载到对象中。 Depending on source, app.config or another file, use appropriate loader. 根据源,app.config或其他文件,使用适当的加载程序。

using System.Collections.Generic;
using System.Xml.Serialization;
using System.Configuration;
using System.IO;
using System.Xml;

class Program
{
    static void Main(string[] args)
    {
        var section = SectionSchool.Load();
        var file = FileSchool.Load("School.xml");
    }
}

File loader: 文件加载器:

public class FileSchool
{
    public static School Load(string path)
    {
        var encoding = System.Text.Encoding.UTF8;
        var serializer = new XmlSerializer(typeof(School));

        using (var stream = new StreamReader(path, encoding, false))
        {
            using (var reader = new XmlTextReader(stream))
            {
                return serializer.Deserialize(reader) as School;
            }
        }
    }
}

Section loader: 节装载机:

public class SectionSchool : ConfigurationSection
{
    public School Content { get; set; }

    protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
    {
        var serializer = new XmlSerializer(typeof(School)); // works in     4.0
        // var serializer = new XmlSerializer(type, null, null, null, null); // works in 4.5.1
        Content = (Schoool)serializer.Deserialize(reader);
    }
    public static School Load()
    {
        // refresh section to make sure that it will load
        ConfigurationManager.RefreshSection("School");
        // will work only first time if not refreshed
        var section = ConfigurationManager.GetSection("School") as SectionSchool;

        if (section == null)
            return null;

        return section.Content;
    }
}

Data definition: 数据定义:

[XmlRoot("School")]
public class School
{
    [XmlAttribute("Name")]
    public string Name { get; set; }

    [XmlElement("Student")]
    public List<Student> Students { get; set; }
}

[XmlRoot("Student")]
public class Student
{
    [XmlAttribute("Index")]
    public int Index { get; set; }
}

Content of 'app.config' 'app.config'的内容

<?xml version="1.0"?>
<configuration>

  <configSections>
    <section name="School" type="SectionSchool, ConsoleApplication1"/>
  </configSections>

  <startup> 
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>

  <School Name="RT">
    <Student Index="1"></Student>
    <Student />
    <Student />
    <Student />
    <Student Index="2"/>
    <Student />
    <Student />
    <Student Index="3"/>
    <Student Index="4"/>
  </School>

</configuration>

Content of XML file: XML文件的内容:

<?xml version="1.0" encoding="utf-8" ?>
<School Name="RT">
  <Student Index="1"></Student>
  <Student />
  <Student />
  <Student />
  <Student Index="2"/>
  <Student />
  <Student />
  <Student Index="3"/>
  <Student Index="4"/>
</School>

posted code has been checked in Visual Studio 2010 (.Net 4.0). 已在Visual Studio 2010(.Net 4.0)中检查已发布的代码。 It will work in .Net 4.5.1 if you change construction of seriliazer from 如果你改变seriliazer的构造,它将在.Net 4.5.1中工作

new XmlSerializer(typeof(School))

to

new XmlSerializer(typeof(School), null, null, null, null);

If provided sample is started outside debugger then it will work with simplest constructor, however if started from VS2013 IDE with debugging, then change in constructor will be needed or else FileNotFoundException will occurr (at least that was in my case). 如果提供的示例在调试器外部启动,那么它将使用最简单的构造函数,但是如果从带有调试的VS2013 IDE启动,则需要更改构造函数,否则将发生FileNotFoundException(至少在我的情况下)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM