应用程序配置和动态加载7----自定义应用程序配置

 

自定义应用程序配置

为了让自己编写的程序更加具有灵活性,往往需要把一些信息放置到程序的外部,等到程序运行时,根据读入的数据的不同,可能让程序具有不同的表现。存放这些信息的文件就称为应用程序的配置文件,有的人将配置信息写入ini的文件中,有的应用程序把这些信息写入数据库。在.Net中,一般采用标准的XML文件作为配置文件。不同的应用程序配置文件的名称不同。在.Netweb程序的配置文件一般叫web.config,应用程序的配置文件一般叫app.config

由于配置文件就是一个XML文件所以称文件中的每一个结点为元素。每个XML中的元素都对应一个配置信息,所以又称元素在配置信息中为配置元素,如果一个配置元素中还包含其他的配置元素,那么就称这个配置元素为配置节。

下面具体看一个.Net中具体使用的配置文件,观察一下配置文件的格式。为了能让大家看清楚配置文件的组成,对文中的一些内容进行了省略,用“…”来表示。

<?xml version="1.0"?>

<configuration>

       <configSections>

                            <section name="script" type="...ScriptingSection"/>

                            <sectionGroup name="webServices" type="...SectionGroup">                                      <section name="roleService" type="...Section"/>

                        </sectionGroup>

       </configSections>

       <appSettings>

              <add key="DAL" value="SQLDAL"/>

              <add key="BLL" value="BLL"/>

       </appSettings>

       <connectionStrings>

              <add name="northWindConnectionString" connectionString="Data ..." />

       </connectionStrings>

</configuration>

从上面可以看出,一个配置文件具有根元素configuration,与命名空间System.Configuration中的类Configuration相对应。在根元素configuration中包含的内容一般分为两个部分。第一部分位于configSections中,称为配置节的声明部分。剩下的部分就称为配置节区域,里面包含有很多的配置信息,每一个配置信息,称为一个配置元素或者配置节,配置节还可以包含配置节。像上面文件中

       <appSettings>

              <add key="DAL" value="SQLDAL"/>

              <add key="BLL" value="BLL"/>

       </appSettings>

就是一个配置元素。相对应的connectionStrings是另外的一个配置元素。在配置文件中配置区域的每一个配置元素或者配置节都需要在configSections先声明,然后在后面的配置信息中才能使用。否则,程序会提示“不能识别的配置元素”的提示。这个就像编程中使用的变量首先要声明一样。

配置节的声明部分,比如<section name="script" type="...ScriptingSection"/>中,name就表示下面将要使用到的配置节的名称。type就表示对这个配置信息的处理程序,如果使用的程序集是私有程序集时 type通常由两部分组成,由逗号“,”分隔,前半部分是类型名称,后半部分是程序集名称。如果是公有程序集(),则需要提供publicKey。比如一个使用了强命名程序集的完整声明为:<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

configSections.NET Framework中的configSections元素相对应,在configSections元素中可以包含在表11-5中列出的子元素。

元素的名称

说明

clear

移除对继承的节和节组的所有引用

remove

移除对继承的节和节组的引用

section

定义配置节处理程序与配置元素之间的关联

sectionGroup

定义配置节处理程序与配置节之间的关联

如果配置文件中包含 configSections 元素,则 configSections 元素必须是 configuration 元素的第一个子元素。

在配置文件中的配置节在System.Configuration命名空间中有相应的类与之对应,这样做的目的是提供对这些节的操作,configuration与类Configuration相对应,配置节对应的类使用ConfigurationSection类来表示。可以使用该类提供的GetSection或者GetSectionGroup方法来读取配置文件中的信息。而ConfigurationManager类封装了对这些配置节的操作,并且该类还具有两个属性,AppSettingsConnectionStrings,这两个属性分别与配置文件中的appSettingsconnectionStrings配置节相对应,appSettings返回一个NameValueCollection,而connectionStrings返回一个ConnectionStringSettingsCollection类。根据上面讲解的知识,不但能够读取.NET Framework中已经定义好的内置结点的信息,也可以自定义结点。

11.4.1使用.Net内置结点和.Net内置处理程序

在目录InElementAndMethod中添加一个控制台应用程序InElementAndMethod,在该应用程序中,添加一个配置文件,然后将配置文件中的信息打印出来。

配置文件的内容:

<?xml version="1.0"?>

<configuration>

  <!-- 使用.Net内置的结点和处理程序 -->

  <appSettings>

    <add key="Name" value="TraceFact.Net"/>

    <add key="Version" value="v1.0.08040301" />

    <add key="Language" value="Chinese" />

  </appSettings>

</configuration>

main函数中读取这些信息,并打印出来。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Configuration;//手工添加

 

 

namespace InElementAndMethod

{

    class Program

    {

        static void Main(string[] args)

        {

            string Name = ConfigurationManager.AppSettings["Name"];

            string Language = ConfigurationManager.AppSettings["Language"];

            string Version = ConfigurationManager.AppSettings["Version"];

            Console.WriteLine("名称:{0},版本:{1},语言:{2}", Name, Version, Language);

            Console.ReadKey();

 

        }

    }

}

由于控制台应用程序并不包含System.Configuration.dll程序集,所以如果要使用ConfigurationManager类,必须首先在项目中添加该引用。

程序的运行结果为:名称:TraceFact.Net,版本:v1.0.08040301,语言:Chinese

大家在配置文件App.config中并没有看到configSections 配置节声明部分,而是直接包含了appSettings配置节,依然能使用appSettings配置节,并没有出现未识别的配置元素的异常,那么现在在配置文件中再添加一个自己定义的配置节。看一下会出现什么样的问题。

新添加的配置节

<VS2008>

    <add key="Year"  value="2008"/>

    <add key="Company"  value="MicroSoft"/>

</VS2008>

重新编译程序,会看到图11-24的信息

11-24

运行程序会出现图11-25的异常

11-25

为什么appSettings配置节都没有问题,而VS2008就不行呢?这是因为appSettings是系统内部定义的结点,在系统内有一个文件machine.config,该文件主要设置一些具有具有全局方面的设置,以提供全局服务。该文件一般在C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/CONFIG目录中,打开该文件,可以看到图11-26所示的信息。

11-26

虽然在程序InElementAndMethod的配置文件中没有明确的声明appSettings配置节,没有指定它在.NET中的处理程序,但是在machine.config中已经提前声明了,所以在程序中能直接使用。能不能仿照appSettings配置节的声明,在自己的程序中也声明一下,是不是自己定义的配置节也就能够使用了呢?

machine.config文件中关于appSettings配置节的声明部分,拷贝到App.config文件中。将name改为“VS2008”,然后在main函数中输入下列内容。

 string Year = ConfigurationManager.GetSection("Year").ToString();

string Company = ConfigurationManager. .GetSection("Company") ToString();

仍然不能运行,原因在什么地方呢?

11.4.2使用自定义结点和.Net内置处理程序

上面示例中,自己写了一个VS2008的配置节结点,然后仿照appSettings配置节的声明部分,在应用程序的配置文件也进行了声明,可是依然不能使用,原因在于声明部分的type指出的类型上面。VS2008声明的类型是System.Configuration.AppSettingsSection,这个数据集是为appSettings配置节专门编写的处理程序。所以在VS2008配置节中不能使用,现在需要提供自己的处理VS2008配置节的处理程序。

.Net中已经提供了3个处理配置节的处理程序,它们是System.Configuration.SingleTagSectionHandler   System.Configuration.DictionarySectionHandler System.Configuration.NameValueSectionHandler

 

System.Configuration.SingleTagSectionHandler,只能够处理形如

<VS008  Year="2008"  Company="MicroSoft"/>这样的标签。

System.Configuration.NameValueSectionHandler就能够处理

<VS2008>

    <add key="Year"  value="2008"/>

    <add key="Company"  value="MicroSoft"/>

</VS2008>

这样的配置节,其实ConfigurationManager.AppSettings 返回的就是一个NameValueCollection(表示可通过键或索引访问的关联String类型的键和String类型的值的集合,在命名空间System.Collections.Specialized)。为了演示这两种处理程序,修改App.config,如下:

<?xml version="1.0"?>

<configuration>

  <!-- 使用.Net内置的结点和处理程序 -->

  <configSections>   

    <section name="VS2008_1" type="System.Configuration.SingleTagSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

    <section name ="VS2008_2" type="System.Configuration.NameValueSectionHandler,System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

  </configSections>

  <appSettings>

    <add key="Name" value="TraceFact.Net"/>

    <add key="Version" value="v1.0.08040301" />

    <add key="Language" value="Chinese" />

  </appSettings> 

  <VS2008_1  Year="2008"  Company="MicroSoft"/>

  <VS2008_2>

    <add key="Year"  value="2008"/>

    <add key="Company"  value="MicroSoft"/>

  </VS2008_2>

  </configuration>

读取配置文件信息的完整的代码如下:

using System;

using System.Collections;

using System.Linq;

using System.Text;

using System.Configuration;//手工添加,用到ConfigurationManager

using System.Collections.Specialized;//手工添加,用到NameValueCollection

 

namespace InElementAndMethod

{

    class Program

    {

        static void Main(string[] args)

        {

            string Name = ConfigurationManager.AppSettings["Name"];

            string Language = ConfigurationManager.AppSettings["Language"];

            string Version = ConfigurationManager.AppSettings["Version"];

            Console.WriteLine("名称:{0},版本:{1},语言:{2}", Name, Version, Language);

            //采用SingleTagSectionHandler处理程序,得到哈希表

            Console.WriteLine("采用SingleTagSectionHandler处理程序.");

            Hashtable VS2008_1 =(Hashtable)ConfigurationManager.GetSection("VS2008_1");           

            Console.WriteLine("Year{0}Company{1}", (string)VS2008_1["Year"], (string)VS2008_1["Company"]);

            Console.WriteLine("采用NameValueSectionHandler处理程序.");

            //采用NameValueSectionHandler处理程序,得到NameValueCollection

            NameValueCollection VS2008_2 = (NameValueCollection)ConfigurationManager.GetSection("VS2008_2");           

            foreach (string key in VS2008_2.Keys)

            {

                Console.WriteLine("{0}={1}", key, VS2008_2[key]);

            }

            Console.ReadKey();

        }

    }

}

运行程序,结果是:

名称:TraceFact.Net,版本:v1.0.08040301,语言:Chinese

采用SingleTagSectionHandler处理程序.

Year2008CompanyMicroSoft

采用NameValueSectionHandler处理程序.

Year=2008

Company=MicroSoft

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值