上次用到配置文件,就花了一些时间研究了一下.Net2.0下的配置文件架构,当时感觉确实很强大,完善,但看的有些头晕.迷迷糊糊把实现了要求,就没有再深入研究.
最近,想在配置文件里实现一个复杂的配置,多层次嵌套的配置文件,再把.Net中的配置文档研究了一下,经过这两次的研究,终于彻底搞清楚了。在博客园里已经看到了一篇文章提到了新的配置的研究,地址在这里 http://www.cnblogs.com/Xrinehart/archive/2005/12/03/289978.html 疾风 风行者。文中提到了几个问题,我先补充一下。

引用:
OpenMappedExeConfiguration()有两种重载,我只尝试成功了上述这种,另外一种说是可以从指定配置文件中得到配置对象,但我没成功过,谁要是搞明白了,记得告诉我下。

 

1   ExeConfigurationFileMap filemap = new ExeConfigurationFileMap();
2   filemap.ExeConfigFilename = AppDomain.CurrentDomain.SetupInformation.ApplicationBase+"schema.config";
3   Configuration config;
4   config = ConfigurationManager.OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None);
5
6

 


以上这个方法就可以打开任意的配置文件。

引用:

请教一下,如果有类似下面的树型结构,有没有好的方法吗?
<job name="all">
<job name="power" command="power on"/>
<job name="test tv">
<job name="step1.1" command="turn on tv" />
<job name="step1.2" command="turn off tv" />

这个功能是完全可以实现的。方法如下
示例如下:
  [ConfigurationProperty("jobs")]
  [ConfigurationCollection(typeof(JobCollection),
            AddItemName="job")]
  public JobCollectionSchemaCollection
  {
   get
   {
    return (JobCollection)this["jobs"];
   }
   set
   {
    this["jobs"] = value;
   }
  }
AddItemName,只要设置了AddItemName这个属性,显示出来的配置文件就是你要求的那样了。从这里也可以看出.Net的架构非常全面,很多功能可能我们都还没有用起来。


我是从System.Configuration命名空间开始研究的。从使用架构的角度,我着重研究了以下几个类的功能。
ConfigurationElement
ConfigurationElementCollection
ConfigurationSection
ConfigurationSectionGroup

我认为,如果要自定义强类型的配置内容,理解以下内容非常重要。
假设我现在的命题是要读写如下的配置文件

    <DataBaseSchemaConfig>
        <Schemas>
            <add SchemaName="TestDataBase" SchemaVersion="1.0" SchemaFlag="1_0" />
            <add SchemaName="TestDataBase2" SchemaVersion="1.1" SchemaFlag="1_1">
                <Tables>
                    <add TableName="T_TEST_TABLE" TableDesc="测试表">
                        <Columns>
                            <add ColumnName="ID" ColumnDesc="标识" ColumnType="System.Int32" />
                            <add ColumnName="Name" ColumnDesc="名称" ColumnType="System.String" />
                            <add ColumnName="Desc" ColumnDesc="描述" ColumnType="System.String" />
                        </Columns>
                    </add>
                </Tables>
            </add>
        </Schemas>
    </DataBaseSchemaConfig>
SectionGroup就是一组Session,这个很好理解。
Section是配置文件中一个节。每一个节都对应了系统中的一个强类型的Section对象,该Section对象将用来处理对应的Section。如果你用系统内置的一些Section对象,那么配置文件的内容就会受到很大的限制。从Configuration的架构来看,应当是派生自己的Section对象用来处理自己的需求。好,下面就上面的命题来看看实现
首先:
我们需要一个根节点,我定义为
 public sealed class DataBaseSchemaConfigSection : ConfigurationSection {
该节点作为整个配置节的入口。 

从配置文件可以看出,根节下面是一个Schemas元素。里面包含了很多Schema元素。可以看出这是一个集合。
所以很自然的,我们应当在DataBaseSchemaConfigSection中加入一个集合对象,这个集合对象用来管理Schema元素对应的对象,也就是我们需要一个 ConfigurationElementCollection
public sealed class DataBaseSchemaCollection : ConfigurationElementCollection

这个对象就可以用来管理下面的Schema对象
public sealed class DataBaseSchemaSection : ConfigurationSection

再往下,实际和前面的型式完全一样,是一层一层嵌套下来的。
public sealed class DataBaseTableCollection : ConfigurationElementCollection
public sealed class DataBaseTableSection : ConfigurationSection
public sealed class DataBaseColumnCollection : ConfigurationElementCollection
public sealed class DataBaseColumnSection : ConfigurationSection

实际上整个的配置文件就是Section,ConfigurationElement的反复使用。
理解了整个架构之后,就可以非常轻松的写出读写自己自定义的配置信息。

从对象到配置文件中的对应,是通过对象的自定义属性实现的。如:

 

        [ConfigurationProperty("ColumnName",IsKey=true,IsRequired=true)]
        
public string ColumnName {
            
get 
                
return (string)this["ColumnName"];
            }

            
set {
                
this["ColumnName"= value;
            }

        }

 

实际对象的属性数据是保存在祖先类中的,你需要作的是强类型转换成你自己类型。
另外,在自定义属性中,最重要的是元素名称,有可能是Section名称,也可能是作为元素的属性名称。

差不多,理解到这里,基本的应用就应当没有问题了。
再深入研究一下,基实自定义配置的序列化也是可以控制的。准备以后有需要的时候再进行研究。

posted on 2006-08-25 23:28  上善若水  阅读(6985)  评论(5编辑  收藏  举报