[C#.NET] 載入自訂 Configuration Section

[C#.NET] 載入自訂 Configuration Section

續上篇 http://www.dotblogs.com.tw/yc421206/archive/2015/06/20/151599.aspx

若你的參數檔來源並非App.config | Web.config,ConfigurationManager 另外提供了載入其他 Xml 檔案的功能,以 Open 前綴詞,直接看範例

如下範例:

  1. ConfigurationManager.OpenMappedMachineConfiguration 開啟一外部 Xml 檔案
  2. CreateDefault 建立了預設的 MySection 及 MySectionGroup 類別
  3. Configuration.Save 將建立的檔案儲存起來

public static Configuration LoadFile(string targetXmlPath, bool isCreateDefault = false)
{
    var config = ConfigurationManager.OpenMappedMachineConfiguration(new ConfigurationFileMap(targetXmlPath));
    if (isCreateDefault)
    {
        DefaultSettings(config);
    }
    return config;
}
private static void DefaultSettings(Configuration config)
{
    var section = config.Sections["Section"];
    if (section == null)
    {
        MySection mySection = new MySection();
        mySection.Code = "9999";
        mySection.Member.Id = 100;
        mySection.Member.Name = "Sys";
        config.Sections.Add("Section", mySection);
    }

    var sectionGroup = config.SectionGroups["SectionGroup"];

    if (sectionGroup == null)
    {
        sectionGroup = new MySectionGroup();
        config.SectionGroups.Add("SectionGroup", sectionGroup);
        var mySection1 = new MySection() { Code = "1", Member = new MemberElement() { Id = 1, Name = "yao1" } };
        var mySection2 = new MySection() { Code = "2", Member = new MemberElement() { Id = 2, Name = "yao2" } };
        sectionGroup.Sections.Add("Section1", mySection1);
        sectionGroup.Sections.Add("Section2", mySection2);
    }
    config.Save(ConfigurationSaveMode.Minimal);
}

完整範例如下:

https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.CustomConfiguration/Simple.CustomConfiguration/MySection.cs

調用端程式碼如下:

  1. App1.config:copy always 必須是一個標準的 Xml 內容格式,我已經在測試專案建立了該檔案,並將它輸出到bin
  2. ConfigurationManager 裡面已經包含了 App.config 的Section,App.config 最後會輸出成 UnitTestProject1.dll.config

[TestMethod]
public void LoadFile_CreateDefault_TestMethod()
{
    var filePath = Directory.GetCurrentDirectory() + "\\" + "App1.config";

    MySection.LoadFile(filePath, true);
    var section = (MySection)ConfigurationManager.GetSection("Section");
    var mySection = (MySection)ConfigurationManager.GetSection("MySection");
    Assert.AreEqual("9999", section.Code);
    Assert.AreEqual(100, section.Member.Id);
    Assert.AreEqual("Sys", section.Member.Name);

    Assert.AreEqual("23", mySection.Code);
    Assert.AreEqual(2, mySection.Member.Id);
    Assert.AreEqual("余小章", mySection.Member.Name);
}

 

最後產生完整的 Xml 內容如下


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="Section" type="Simple.CustomConfiguration.MySection, Simple.CustomConfiguration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <sectionGroup name="SectionGroup" type="Simple.CustomConfiguration.MySectionGroup, Simple.CustomConfiguration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" >
            <section name="Section1" type="Simple.CustomConfiguration.MySection, Simple.CustomConfiguration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
            <section name="Section2" type="Simple.CustomConfiguration.MySection, Simple.CustomConfiguration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        </sectionGroup>
    </configSections>
    <Section Code="9999">
        <Member Id="100" Name="Sys" />
    </Section>
    <SectionGroup>
        <Section1 Code="1">
            <Member Id="1" Name="yao1" />
        </Section1>
        <Section2 Code="2">
            <Member Name="yao2" />
        </Section2>
    </SectionGroup>
</configuration>

 

這裡衍生出一個問題

若相同的 *.config 有相同的 Section ,ConfigurationManager 會如何處理?

我在測試專案加入 App2.config:copy always,並建立與 App.config 相同的區段 MySection,Code 設為 36

image

 

測試結果 Code 並非 36,表示 ConfigurationManager 在碰到重覆的 Section 會以 App.config 的為主


[TestMethod]
public void LoadFile_TestMethod()
{
    var filePath = Directory.GetCurrentDirectory() + "\\" + "App2.config";

    var mySection = (MySection)ConfigurationManager.GetSection("MySection");
    MySection.LoadFile(filePath, false);

    Assert.AreEqual("36", mySection.Code);
}

完整測試程式碼如下:

https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.CustomConfiguration/UnitTestProject1/UnitTest1.cs

 


本文出自:http://www.dotblogs.com.tw/yc421206/archive/2015/06/20/151602.aspx

 

專案位置:https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.CustomConfiguration/

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo