65.9K
CodeProject 正在变化。 阅读更多。
Home

类库项目的配置文件

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.64/5 (7投票s)

2007年3月8日

CPOL

3分钟阅读

viewsIcon

84113

downloadIcon

629

本文介绍了如何为 DLL 程序集(使用 .NET 1.1 创建)创建自定义 ConfigurationManager,该程序集可以从基于 XML 的配置文件中加载配置设置。

Screenshot - screen_main.jpg

引言

在使用 .NET 1.1 中的 Windows 窗体和 Web 窗体应用程序时,我们意识到可以轻松地从配置文件中加载应用程序设置。.NET 配置体系结构使加载这些文件并在运行时在应用程序中读取它们变得非常容易。但是,有时我们会开发复杂的业务组件,这些组件必须具有自己的配置相关数据。由于这些库组件独立于加载它们的应用程序,因此这些组件必须具有自己的 ConfigurationManager 是有道理的。本文介绍了如何为 DLL 开发配置管理器。我从 .NET 2.0 配置体系结构中获得了灵感,并尝试使这个管理器类与 Framework 2.0 中的完全相同。鼓励尚未使用的 .NET 2.0 提供的 ConfigurationManagerWebConfigurationManager 的读者阅读本文的背景部分。

背景

由于本文中的代码结构围绕 Framework 1.1 和 2.0 中存在的配置体系结构展开,因此最好先了解如何在两个版本的 Framework 中读取配置文件。

Framework 1.1

<!-- app.config -->

<configuration>
    <configSections>
        <section name="MyTempSection"
		type="System.Configuration.SingleTagSectionHangler" />
        <section name="CustomSection1"
		type="System.Configuration.DictionarySectionHandler" />
    </configSections>

    <MyTempSection amount="7500" currency="USD" />
    <customSection1>
        <add key="name" value="Muhammad" />
        <add key="lastName" value="Irfan" />
    </customSection1>

</configuration>
//To read above configuration sections we can use the following code:

IDictionary section = System.Configuration.ConfigurationSettings.GetConfig
	("MyTempSection") as IDictionary
String amount = section["amount"] ;
String currency = section["currency"];

IDictionary section1 = System.Configuration.ConfigurationSettings.GetConfig
	("CustomSection1") as IDictionary;

String name = (string) section1"name"];
String lastName = (string) section1["lastName"]

对于 app.config 中的节类型,我使用了 SingleTagSectionHandlerDictionarySectionHandler,只是为了使示例清晰。如果要将配置数据加载到您自己的类型中,那么可以通过实现 IConfigurationSectionHandler 来声明自定义类型。SingleTagSectionHandler 使用 XML 属性将配置设置指定为键值对,而 DictionarySectionHandler 允许将配置信息指定为 XML 节点中的名称值对。在 .NET 2.0 中,配置体系结构更加简化和增强。Framework 2.0 包含 WebConfigurationManagerConfigurationManager,它们是该体系结构的核心。添加了 ConnectionStrings 属性,用于检索 ConnectionStringSection。通过使用 connnectionStringSection,我们可以获取 connectionStringSettingsCollection 并枚举该节的所有属性。以下代码演示了如何使用自定义配置节。

Framework 2.0

<!-- app.config -->
<configuration>
    <configSections>
        <sectionGroup name="MySectionGroup">
            <section name="settings" type="[NameSpace].[Class_Name], [AssemblyName]" />
        </sectionGroup>
    </configSections>

    <MySectionGroup>
        <settings dbProvider="System.Data.SqlClient" dbName="SPR01" />
    </MySectionGroup>
</configuration>
//Once again to read the above section we can use the following code
System.Configuration.Configuration webConfig =
	System.Configuration.ConfigurationManager.OpenExeConfiguration
	(ConfigurationUserLevel.PerUserRoamingAndLocal);
Test_Desktop_2005.MyCustomConfigurationHandler config =
	(Test_Desktop_2005.MyCustomConfigurationHandler)webConfig.GetSection
	("MySectionGroup/settings");

string dbProvider = config.DBProvider;
string dbName = config.DBName;

// Class that creates the configuration handler
public class MyCustomConfigurationHandler : ConfigurationSection
{
    // Empty Construct
    public MyCustomConfigurationHandler() { }
    // Loaded Construct
    public MyCustomConfigurationHandler(string dbProvider, string dbName)
    {
        DBProvider = dbProvider;
        DBName = dbName;
    }

    // First Number Property
    [System.Configuration.ConfigurationProperty("dbProvider",
	DefaultValue = "", IsRequired = true, IsDefaultCollection = false)]
    public string DBProvider
    {
        get
        {
            return (string)this["dbProvider"];
        }
        set
        {
            this["dbProvider"] = value;
        }
    }

    // Second Number Property
    [System.Configuration.ConfigurationProperty("dbName",
	DefaultValue = "", IsRequired = true, IsDefaultCollection = false)]
    public string DBName
    {
        get
        {
            return (string)this["dbName"];
        }
        set
        {
            this["dbName"] = value;
        }
    }
} 

Using the Code

附件是演示如何有效使用 ConfigurationManager 类的演示项目。我们将使用 XML 文件 Configuration.xml 作为配置文件。在项目中,您可以浏览并找到该文件。如果您查看代码,您会发现使用我们的 ConfigurationManager 与在 .NET 2.0 中使用 ConfigurationManager 相同。它包含具有相同名称和参数的方法。对于加载 XML 文件,我使用了 XPathNavigator,因为它不像 XmlDocumentXmlNode 那样构建节点树;而是每次只查看一个节点。当您移动到它们时,它会构建节点。它不会使用太多内存,因为它不会在开始时创建整个节点树。它会在您浏览文件时动态创建树。

<!-- Configuration.xml -->
<configuration>
    <cofigSection>
        <globalThreshold amount="7500" currency="7500" />
        <general>
            <add key="key1" value="value1" />
            <add key="key2" value="value2" />
            <add key="key3" value="value3" />
            <add key="key4" value="value4" />
        </general>
    </cofigSection>

    <connectionStrings>
        <add name="connection1" connectionString="connection_string_for_connection_1"
		provider="System.Data.SqlClient" />
        <add name="connection2" connectionString="connection_string_for_connection_2"
		provider="System.Data.Oledb" />
    </connectionStrings>

    <appSettings>
        <add key="WindowState" value="Maximized" />
    </appSettings>

</configuration> 

ConfigurationManager 有一个 public 方法,即 OpenExeConfiguration。它接受 config 文件路径并返回 configuration 对象。

ConfigurationManager manager = new ConfigurationManager();
Configuration configuration = manager.OpenExeConfiguration
				(this.openFileDialog1.FileName);

一旦我们获得了 configuration 对象,我们就可以使用它提供的相关属性直接访问 appSettingconnectionString 值。LoadSingleSection() 方法使用该节的名称从连接字符串节集合中加载单个节。ConnectionStringsSettingsCollection 实现了 IDictionary,因此使用著名的运算符 [] 访问节点属性变得很容易。以下代码演示了这一点

NameValueCollection appSettingCollection = configuration.AppSettings.Settings;
string windowState = appSettingCollection["WindowState"];

ConnectionStringSection connectionStringSection = configuration.ConnectionStrings;
ConnectionStringsSettingsCollection sectionCollection =
	connectionStringSection.LoadSingleSection("connection1");

string connectinString = sectionCollection["connectionString"]);
string connectionName = sectionCollection["name"]);
string dbProvider = sectionCollection["provider"]);

我们还可以使用 configuration 对象的 GetSection() 方法从我们的 configuration.xml 中读取自定义节。此管理器类的另一个重要方法是 GetAllChildsOfSection(),它返回节的所有子节点。包含此方法的目的是它为我们提供了特定节的 <add> 节点及其键值对。它的工作方式与 configurationAppSettings 属性类似,后者返回 <AppSetting> 节的键值。以下代码片段显示了如何使用 GetSection()GetAllChildsOfSection() 方法。

ConfigurationSection customSection = configuration.GetSection("globalThreshold");
string amount = customSection["amount"];

NameValueCollection generalConfigurationsCollection =
	configuration.GetAllChildsOfSection("//cofigSection/general");

虽然我们使用了 OpenFileDialog 来定位文件,但在组件/类库将被 Web/Windows 窗体应用程序使用的实际场景中,
我们可以将 configuration.xml 放在加载组件的同一目录中。

Configuration configuration = manager.OpenExeConfiguration
	(System.AppDomain.CurrentDomain.BaseDirectory+@"Configuration.xml"); 

历史

  • 2007 年 3 月 8 日:首次发布
© . All rights reserved.