自定义配置节点的思考
如何在web.config中配置自定义的节点,网上有很多这方面的文章,我这里只想说说在.net framework中如何实现的。由于结合例子比较好说明问题,下面来看个例子。
1.假设在web.config有这样一段自定义的代码:
2 <Passport defaultProvider="SqlServerDataProvider">
3 <providers>
4 <add name="SqlServerDataProvider" type="Itelite.Passport.SqlDataProvider.Database,Itelite.Passport.SqlDataProvider"
5 connectionString="database=Forums;server=.;User ID=sa;Password=apple;"
6 databaseOwner="dbo" />
7 <add name="AcessDataProvider" type="Itelite.Passport.AcessDataProvider.Database,Itelite.Passport.AccessDataProvider"
8 connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}"
9 databaseOwner="~/db.config" />
10 </providers>
11 </Passport>
12 </Itelite>
2. 为了获取自定义的内容,我们需要写一个类来继承IConfigurationSectionHandler.这个接口只有一个方法:
1internal class ConfigurationHandler : IConfigurationSectionHandler
2 {
3 public object Create(Object parent, Object context, XmlNode node)
4 {
5 Config config = new Config();
6 config.LoadValuesFromConfigurationXml(node);
7 return config;
8 }
9 }
先别管这个方法里的代码,后面再交代.
3. 问题来了,我们写这个方法在哪里调用呢?又怎么获取web.config自定义节点的内容呢?
先讲答案:我们只需要调用System.Configuration.ConfigurationSettings.GetConfig("Itelite/Passport");就可以获取节点的内容了.这个方法的返回值就是Create(...)方法返回的结果.再来分析一下下:使用Reflector打开.net framework1.1中system.dll,找到ConfigurationSettings类.该类中的GetConfig()是调用DefaultConfigurationSystem的GetConfig(),而这个类的GetConfig又是调用ConfigurationRecord类的GetConfig().ConfigurationRecord类的GetConfig()接着调用了如下方法:ResolveConfig()-->Evaluate()-->EvaluateRecursive().而就是在EvaluateRecursive()里调用了第2步中我们自定义的方法. 问题又来了,EvaluateRecursive()怎么知道我定义的那个类(ConfigurationHandler)呢?在Evaluate()方法里会根据我们在web.config配置中的type来找.如果从type的dll文件中没有任何类继承IConfigurationSectionHandler,那就要抛出异常来啦.
4. 到此为止我们还没有获取web.config中的connectionString,databaseOwner的值.我们可以定义:
这段代码要自己看哦.
5.有个注意事项: framework2.0已经没有GetConfig()了,所以只能在1.1使用该方式了.