`

web.config-----------ConfigurationSettings 类解析

阅读更多

<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 16.5pt; HEIGHT: 16.5pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image001.gif" o:href="http://bbs.fsll.cn:8090/Images/topicface/face1.gif"></imagedata></shape>

.Net Framework 源码分析

.Net Framework的源码是微软编程大师们智慧的结晶,是我们开发人员梦寐以求的知识宝藏。

挖掘这座宝藏是我们快速提升自身编程思想水平的重要途径。

下面是我研究分析 .Net Framework一部分代码后的一点心得,共享出来,希望对大家有所帮助,当然,分析不对的地方,还望指正,不胜感激。

System.Configuration.ConfigurationSettings

相信大家对这个类都不陌生吧。 ConfigurationSettings类重要的方法是(在我下面的分析中,方法也包括属性)

  • AppSettings属性 用于获取 元素配置节中的配置设置。

  • GetConfig方法 返回用户定义的配置节的配置设置。

在我们的项目开发中,我们经常通过 ConfigurationSettings.AppSettings["myKey"] 的方法 来获取 web.config 配置项上 appSettings 的配置值。调用这个ConfigurationSettings.AppSettings["myKey"]索引器我们就可以获取到 web.cofing 配置项 appSettings 的配置值,这太方便了。如果要我们设计一个这样的功能的时候,我们会有什么想法呢。 我的想法大概的是这样的:

1. 加载 web.config 配置文件的内容

2. 分析 web.config 配置文件配置项 appSettings 节点的内容,并加载到配置项管理类中。

3. 配置项管理类中应该有一个索引器,方便外部系统访问。

让我们来分析大师们是如何实现这个类的。看看大师级人物的代码和设计思路有何高明之处。

//ConfigurationSettings类的定义

public sealed class ConfigurationSettings

{

}

C# 关键字 sealed 表明此类是不能被继承的。

//静态构造函数

static ConfigurationSettings()

{

_initState = InitState.NotStarted;

_initLock = new object();

}

一个类最先运行的代码段就是静态构造函数,并且对于整个程序域而言静态构造函数只运行一次。
C#
关键字 static 加上类名称的方法函数就是静态构造函数。
对于一个类来说,只能有一个静态构造函数。
静态构造函数的作用主要是初始化静态变量。
C#关键字 static 约束的类方法里面的代码都只能调用 静态变量或者静态方法,静态属性等。

静态方法:C#关键字 static 约束的方法就是静态方法(有些教材可能会称为类方法),里面的代码都只能调用 静态变量或者静态方法,静态属性等。

//静态变量的定义代码

private static object _initLock;

C#关键字 static 表明此变量为静态变量。

//构造函数

private ConfigurationSettings()

{

}

发现上面的构造函数跟我们平时所写的类的构造函数有什么不同吗?
对了,就是访问权限的约束关键字 private ,平时构造函数的约束关键字都是 public
那么将构造函数访问权限设置为 private有什么目的呢?

1. 防止别人的代码通过 new 操作生成对象实例。

如:System.Configuration.ConfigurationSettings config = new System.Configuration.ConfigurationSettings();

你会发现上面的代码编译不通过,原因就是访问了 private 的构造函数,当然编译不通过啦!

2. 保证一个类仅有一个实例。

这里就是设计模式中的 Singleton 单件模式了,设置构造函数的访问权限为 private 是实现 Singleton 模式的前提

//AppSettings静态只读属性

public static NameValueCollection AppSettings

{

get

{

ReadOnlyNameValueCollection config = (ReadOnlyNameValueCollection) GetConfig("appSettings");

if (config == null)

{

config = new ReadOnlyNameValueCollection(new

CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture), new CaseInsensitiveComparer(CultureInfo.InvariantCulture));

config.SetReadOnly();

}

return config;

}

}

通过上面的代码我们可以知道,此属性为静态只读属性(static 关键字,只有 get 操作,而没有 set 操作)
因为 NameValueCollection 类定义了索引访问器,所以平时我们的代码都是这样写的 ConfigurationSettings.AppSettings["myKey"]
,对于["myKey"]这种使用 []号访问的索引器,我们下面分析NameValueCollection类时再说明索引器。

ReadOnlyNameValueCollection config = (ReadOnlyNameValueCollection) GetConfig("appSettings");
注意到参数的值是 appSettings 了吗?
是不是跟我们 web.config 里面的 appSettings 的配置节点项有关联呢?他们有什么关系吗?我们往下看。
这段代码调用了ConfigurationSettings类的另外一个静态方法,代码如下:

public static object GetConfig(string sectionName) //当然这时 sectionName == "appSettings"

{

if ((sectionName == null) || (sectionName.Length == 0))

//判断 string 的值是不是为Empty时,应该用 sectionName.Length == 0 来判断

{

return null;

}

if (_initState < InitState.Usable)

{

EnsureConfigurationSystem();

}

if (_initError != null)

{

throw _initError;

}

return _configSystem.GetConfig(sectionName);

}



代码段:

if (_initState < InitState.Usable)

{

EnsureConfigurationSystem();

}

InitState 只是一个私有的枚举类型 enum

private enum InitState

{

NotStarted,

Started,

Usable,

Completed

}

刚才ConfigurationSettings类的静态构造函数是设置
initState = InitState.NotStarted;
那么第一次运行时,肯定会执行 EnsureConfigurationSystem()方法了,我们接着看看代码的实现

private static void EnsureConfigurationSystem()

{

lock (_initLock)

{

if (_initState < InitState.Usable)

{

_initState = InitState.Started;

try

{

_configSystem = new DefaultConfigurationSystem();

_initState = InitState.Usable;

}

catch (Exception exception)

{

_initError = exception;

_initState = InitState.Completed;

throw;

}

}

}

}

C#关键字 lock 加锁处理。
lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入一个锁定代码,则它将在释放该对象前一直等待(块)。
MSDN的解释:lock 关键字可将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。
通常,如果要保护实例变量,则 lock(this);如果要保护 static 变量(或者如果临界区出现在给定类的静态方法中),则 lock(typeOf (class))

<shape id="_x0000_i1026" style="WIDTH: 9.75pt; HEIGHT: 11.25pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image002.gif" o:href="http://bbs.fsll.cn:8090/Images/list/ip.gif"></imagedata></shape>2007-7-24 13:57:32

陈英豪

<shape id="_x0000_i1027" style="WIDTH: 24pt; HEIGHT: 24pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image003.gif" o:href="http://bbs.fsll.cn:8090/Images/face/image52.gif"></imagedata></shape>
<shape id="_x0000_i1028" style="WIDTH: 82.5pt; HEIGHT: 7.5pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image004.gif" o:href="http://bbs.fsll.cn:8090/Images/star/level10.gif"></imagedata></shape>
等级:版主
文章:17
积分:19
注册:2007-7-2

<shape id="_x0000_i1029" style="WIDTH: 45pt; HEIGHT: 13.5pt" type="#_x0000_t75" alt="给2AE6E5308869449895CF7EDAAB814568发送一个短消息" href="http://bbs.fsll.cn:8090/smsWrite.aspx?touser=2AE6E5308869449895CF7EDAAB814568" target="_blank" o:button="t"><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image005.gif" o:href="http://bbs.fsll.cn:8090/Images/list/message.gif"></imagedata></shape><shape id="_x0000_i1030" style="WIDTH: 36pt; HEIGHT: 13.5pt" type="#_x0000_t75" alt="把2AE6E5308869449895CF7EDAAB814568加入好友" href="http://bbs.fsll.cn:8090/listFriends.aspx?action=add&amp;myFriend=2AE6E5308869449895CF7EDAAB814568" target="_blank" o:button="t"><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image006.gif" o:href="http://bbs.fsll.cn:8090/Images/list/friend.gif"></imagedata></shape><shape id="_x0000_i1031" style="WIDTH: 33.75pt; HEIGHT: 13.5pt" type="#_x0000_t75" alt="查看2AE6E5308869449895CF7EDAAB814568的个人资料" href="http://bbs.fsll.cn:8090/dispuser.aspx?id=2AE6E5308869449895CF7EDAAB814568" target="_blank" o:button="t"><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image007.gif" o:href="http://bbs.fsll.cn:8090/Images/list/profile.gif"></imagedata></shape><shape id="_x0000_i1032" style="WIDTH: 33.75pt; HEIGHT: 13.5pt" type="#_x0000_t75" alt="搜索2AE6E5308869449895CF7EDAAB814568的所有贴子" href="http://bbs.fsll.cn:8090/search.aspx?keyword=2AE6E5308869449895CF7EDAAB814568" target="_blank" o:button="t"><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image008.gif" o:href="http://bbs.fsll.cn:8090/Images/list/find.gif"></imagedata></shape><shape id="_x0000_i1033" style="WIDTH: 33.75pt; HEIGHT: 13.5pt" type="#_x0000_t75" alt="回复这个贴子" href="http://bbs.fsll.cn:8090/post.aspx?action=re&amp;boardid=200&amp;tieid=1082" o:button="t"><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image009.gif" o:href="http://bbs.fsll.cn:8090/Images/list/reply_a.gif"></imagedata></shape>

2

<shape id="_x0000_i1034" style="WIDTH: 16.5pt; HEIGHT: 16.5pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_image001.gif" o:href="http://bbs.fsll.cn:8090/Images/topicface/face1.gif"></imagedata></shape>

_configSystem = new DefaultConfigurationSystem();

private static IConfigurationSystem _configSystem;

_configSystem 是一个接口变量。
先看看接口 IConfigurationSystem 定义

public interface IConfigurationSystem

{

// Methods

object GetConfig(string configKey);

void Init();

}

接着我们跟踪实现了 IConfigurationSystem 接口的 DefaultConfigurationSystem 类看看
类的定义:

internal class DefaultConfigurationSystem : IConfigurationSystem

{

}

C# 关键字 internal 表明此类只能被当前的 dll 里面的类使用。
顺便提一提 protected internal 这样的二个关键字的约束。它表明这个只能被当前 dll 里面的类使用或者不是当前 dll 里面的子类使用,记得是 或者 的关系
我们还是先从这个类的构造函数分析开始:

internal DefaultConfigurationSystem()

{

}

这里的构造函数使用 internal,并不是像 ConfigurationSettings 类构造函数的 private
它的访问权限比 ConfigurationSettings 的类的松一点,允许当前 dll 里面的类可以通过 new 操作来生成多个 DefaultConfigurationSystem 实例。
所以这里才有上面的代码:
_configSystem = new DefaultConfigurationSystem();
的代码调用。
重要方法GetConfig的部分关键代码内容:

object IConfigurationSystem.GetConfig(string configKey) //当然这里还是 configKey == "appSettings"

{

if (!this._isAppConfigInited)

{

this.EnsureInit(configKey);

}

ConfigurationRecord record = null;

if (record != null)

{

return record.GetConfig(configKey);

}

return null;

}

接下来我们就要分析 EnsureInit 方法。

private void EnsureInit(string configKey)

{

try

{

ConfigurationRecord record = new ConfigurationRecord();

bool flag2 = record.Load(this._machineFilename);

//加载配置文件信息,这里是加载 machine.config 的信息,并不是 web.config的信息

this._machineConfig = record;

///....省略

}

catch (Exception exception)

分享到:
评论

相关推荐

    一个利用a Custom XML Configuration 进行ASP.NET网页参数配置而非 web.config的源码例子

    2. 配置读取器:使用`System.Configuration`命名空间中的类,如`XmlConfigurationSectionHandler`或自定义配置处理程序来解析`CustomConfig.xml`文件。创建一个配置节处理器类,如`CustomConfigSectionHandler`: `...

    web.config配置数据库连接

    string myvar = ConfigurationSettings.AppSettings["connstring"]; ``` #### 四、连接字符串参数详解 无论是使用`connectionStrings`还是`appSettings`节点,连接字符串中的参数都至关重要。下面将详细介绍这些...

    Web.config自定义节点使用

    在.NET框架中,`Web.config`文件是ASP.NET应用程序的核心配置文件,用于存储应用程序的配置信息,如连接字符串、身份验证设置、权限控制等。在本文中,我们将深入探讨如何在`Web.config`中添加自定义节点,并读取...

    ASP.NET2005 Web.config详解

    ### ASP.NET 2005 Web.config ...通过以上对 `Web.config` 文件中各配置项的详细解析,我们可以看到这个文件对于 ASP.NET 应用的重要性。合理配置这些选项可以帮助开发者更好地管理应用的行为、安全性以及性能等方面。

    如何修改 app.config 的配置信息

    在C#代码中,可以使用`System.Configuration`命名空间下的类来读取`app.config`中的配置信息: - `ConfigurationManager.AppSettings`: 获取`appSettings`中的键值对。 - `ConfigurationManager....

    读取、存储webconfig几种方法

    Configuration config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(System.Web.HttpContext.Current.Request.ApplicationPath); AppSettingsSection appSection = ...

    webconfig配置数据库连接

    string myvar = ConfigurationSettings.AppSettings["connstring"]; ``` ### 连接字符串参数详解 在配置数据库连接时,理解连接字符串中的各个参数至关重要。以下是对连接SQL Server数据库时常用的几个参数的解释...

    [新手-图文]整合ssm框架-从mybatis到spring-mybatis再到ssm-sping-mybatis-spingmvc

    -- 视图解析器 --&gt; &lt;bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt; &lt;property name="prefix" value="/WEB-INF/jsp/"/&gt; &lt;property name="suffix" value=".jsp"/&gt; &lt;!-- ...

    DOTNET修改webconfig.docx

    首先,`Web.config`文件的数据库连接字符串通常位于`&lt;connectionStrings&gt;`元素内,它属于`&lt;configuration&gt;`的子元素。例如: ```xml &lt;configuration&gt; ... &lt;add name="MyApp.Properties.Settings....

    C#学习心得

    一旦数据库连接字符串被配置在Web.Config中,C#应用程序就可以通过`System.Configuration.ConfigurationSettings.AppSettings`对象来读取它。以下是一个示例: ```csharp string strConn = System.Configuration....

    【ASP.NET编程知识】asp.net实现XML文件读取数据绑定到DropDownList的方法.docx

    string filePath = ConfigurationSettings.AppSettings["LanguageXmlFile"]; lanDS.ReadXml(filePath); if (lanDS.Tables.Count &gt; 0) { foreach (DataRow copyRow in lanDS.Tables[0].Rows) { dt.ImportRow...

    动态调用webservice.doc

    connList.Add("WISTABLE4", System.Configuration.ConfigurationSettings.AppSettings["NWistable4"]); break; case "1": connList.Add("WISTABLE4", System.Configuration.ConfigurationSettings.AppSettings[...

    C#实现网页中上传文件

    这可以通过`System.Configuration.ConfigurationSettings.AppSettings`属性来实现,它提供了一种方便的方式访问应用程序的配置信息。 #### 5. 类和方法设计 为了组织和封装代码,C#提供了类和方法的概念。在给定的...

    SpaceBuilder_V2.3_SP1

    SpaceBuilder.Core/Framework/Configuration/SiteSettings.cs Service/Service/Email/Emails.cs Themes/Manages/Default/Pages/Settings/ManageSiteSetting.aspx Common.Web/Controllers/...

    ssm框架搭建

    - **Spring MVC配置**:配置DispatcherServlet、视图解析器等。 - **MyBatis配置**:配置数据源、SQLSessionFactory等。 ##### Spring MVC配置示例 ```xml &lt;!-- web.xml --&gt; &lt;servlet-name&gt;dispatcher&lt;/servlet-...

    服务器提交了协议冲突. Section=ResponseStatusLine解决方法

    - 对于 Web 应用程序,则需要编辑 `web.config` 文件。 2. **配置内容**: 在配置文件中添加以下内容: ```xml &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;configuration&gt; &lt;settings&gt; &lt;/settings&gt; &lt;/...

    Web2.0社区平台源码

    SpaceBuilder.Core/Framework/Configuration/SiteSettings.cs Service/Service/Email/Emails.cs Themes/Manages/Default/Pages/Settings/ManageSiteSetting.aspx Common.Web/Controllers/ManageSettingsController....

    C#读写配置文件

    该命名空间包含如`ConfigurationManager`类,可以用于读取和写入配置文件。 #### 读取配置文件 1. **获取配置节**:配置文件中的数据被组织成节(如`&lt;appSettings&gt;`或`&lt;connectionStrings&gt;`),可以使用`...

    开发框架搭建

    -- 配置视图解析器 --&gt; &lt;bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt; &lt;property name="prefix" value="/WEB-INF/jsp/"/&gt; &lt;property name="suffix" value=".jsp"/&gt; ``` ...

Global site tag (gtag.js) - Google Analytics