⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 灵活的.net体系结构之简化配置服务.txt

📁 学习(编程技巧_编程知识_程序代码),是学习编程不可多得的学习精验
💻 TXT
字号:
灵活的.NET体系结构之简化配置服务
 

--------------------------------------------------------------------------------
 
第八军团 时间:2003-12-31 12:42:40 
   
应用程序在运行时需要读取配置信息。在.NET环境下这种需求同样必不可少。.NET提供一种基于XML的统一配置文件。就ASP.NET而言,此文件名为web.config。应用程序在运行时能够读取该文件的具体内容。.NET同时还提供了一系列的调用,这些调用可使读取配置文件信息的过程变得相当简单,不过要实现这一点,还需要编写一些C#代码。本文中,我将要提出的解决方案可以进一步简化此过程,同时还提供了一种分层的提取机制,此方案在很大程度上与文件的XML格式无关。 
此外,编程人员不必知道很多有关XML 类以及其他一些XML细节的信息。"配置服务"就是灵活体系结构的入门。如果能够正确利用配置服务,我们就可以此为基础逐步实现下列服务: 

·统一的工厂服务 

·相关的数据访问服务 

·声明的基于信息集的分层数据集服务 

·声明的组件服务 

如果本文中解释配置服务时提到这些服务,指的是上述这些服务的组合。 

下面就让我们开始吧,首先来看一个简单的web.config 文件,该文件中具有一些配置实体。 

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
<configSections> 
<section name="SimpleConfiguration" 
type="MySectionHandler,MyAssembly"> 
</section> 
</configSections> 
<SimpleConfiguration> 
<Module1> 
<section1> 
<key1>value1</key1> 
<key2>value2</key2> 
</section1> 
</Module1> 
<Module2> 
<section1> 
<key1>value1</key1> 
<key2>value2</key2> 
<section1> 
</Module2> 
</SimpleConfiguration> 

.NET 应该如何处理此文件 


如果建立了上述配置文件,您的目的就是要读取该文件中SimpleConfiguration部分的实体信息。要想实现这一点,就应该在.NET中添加以下代码: 

ArrayList modules = 
(ArrayList)System.Configuration.ConfigurationSettings. 
GetConfig("SimpleConfiguration"); 


此行代码可以引发一系列操作。进行上述调用时,.NET 将调用名为SimpleConfiguration的类(在文件中的 configSections部分)并且通过将一个XML结点传递给那个创建方法来调用熟知的Create方法。不论此Create方法返回何种类型的对象,该对象都将会传递给GetConfig(...)的调用者。为了给出一个更加完整的示例,下面就介绍一个此类型处理器的示例代码: 

public class MySectionHandler : IConfigurationSectionHandler 
{ 
public object Create(object parent, object configContext, 
XmlNode section) 
{ 
... Read your xmlnode section 
... return an ArrayList 
} // end of method 
} // end of class 


客户端与处理同种对象的section 处理器之间必须达成一致。在这种情况下,该对象就是指ArrayList。 


如何简化这种方法 


上述方法有不少优点。调用者可获得一个C# 对象,此对象与每一个XML section相对应。您可以拥有数目不限的XML section。另一方面,为了简便起见,您需要做到: 

1.为每一个 section 编写一个类。 

2.解析 XML section 以便将其转变成相应的对象。 

客户端常常希望拥有一个更简单的配置接口。下面就是这样一个简单的示例: 

string value = AppServices.getvalue("/SimpleConfiguration/Module1/section1/key1"); 


一旦我们有了这样一个可以使用的API,就不必再创建新的section处理器了。至少这一点对于简单的配置而言是可以实现的。尽管我认为这只是是简化操作的开始,但我还是对能进一步简化配置而感到惊讶。现在,还是让我们先来对此API再进行一次扩充。 

您经常会发现一些配置关键字是必选的。请务必牢记这一点,如果一个关键字未找到,AppServices.getvalue(...)将会抛出一个异常,而且,客户端可能会指定一个默认值来应对找不到关键字的情况。下面是此API的重载版本,这个版本中将上面所述的情况考虑在内: 

string value = AppServices.getvalue( 
"/SimpleConfiguration/Module1/section1/key1", 
"defaultvalue"); 


API的这个版本在找不到关键字时,不但不会引发异常,相反将会返回已设置的默认值。例如,您可以进行如下操作: 

string value = 
AppServices.getvalue( 
"/SimpleConfiguration/Module1/section1/key1", null); 
if (value == null) 
{ 
// you have just avoided an exception if you care to do so 
} 


通过降低错误率来使关键字不区分大小写也是完全可能的。此方法与Xpath相类似。注意到这一点,下面是该API的又一个版本: 

string xpathExpression = "."; 
string value = AppServices.getXPathvalueString( 
xpathExpression); 


有时候您可能会遇到一个给定的key对应多个结点。这种情况下,您可能希望收到的结点为XML结点。要实现这一点,可以进行如下操作: 

XMLNode node = AppServices.getXPath(xpathExpression); 


我们再回到基本的AppServices.getvalue(key)方法。有时,虽然这里的key是在XML文件中指定的,但它的内容却可能是空白符号。这种情况下,可将该key视为根本不存在。同样,也可以选择让API抛出一个异常。如果要兼顾到此种变化,可以调用另一函数: 

string value = AppServices.getvalueHonourWhiteSpace(key); 


概括一下,截止目前我们已经得到了下列这些函数: 

Public class AppServices 
{ 
// Configuration Service 
public static getvalue(string key); 
// throws an exception if the key is not found or has an 
// empty string 
public static getvalueHonourWhiteSpace(string key) 
// throws an exception if the key is not found 
public static getvalue(string key, string default); 
// returns the default if the key is not found or has an 
// empty string 
public static getvalueHonourWhiteSpace(string key,string default) 
// returns the default if the key is not found 
//Xpath support 
public static getXPathvalue(string key); 
// throws an exception if the key is not found or has an 
// empty string 
public static getXPathvalueHonourWhiteSpace(string key) 
// throws an exception if the key is not found 
public static getXPathvalue(string key, string default); 
// returns the default if the key is not found or has an 
// empty string 
public static getXPathvalueHonourWhiteSpace(string key, string default) 
// returns the default if the key is not found 
// Other future services 
} 


我们在这里所采取的一切方法就是为了真正实现简化。具体实现时,可根据情况选择实现上述API之中的一部分。 


实现配置服务 


将配置服务应用到一个实际的示例,我们将会对相关内容有更清晰的理解。在这个示例中,我们将在Web应用程序中发送电子邮件。可能您已经有了如下所示的一个API : 

public static void sendMail(string from, string to, string subject, string body, 
string format); 


如果使用此 API,则客户端代码将是: 

public static trivialMailExample() 
{ 
string from="support@johndoeinc.com"; 
string to = "johndoe2@customerinc.com"; 
string subject = "Your order is ready"; 
string body="You can pick it up at facility1"; 
string format = "plain-text"; 
sendMail(from,to,subject,body,format); 
} 


正如您所看到的,很难对电子邮件的所有参数进行编码以便嵌入到Web站点中。如果我们想从配置文件中读取这样的一些参数又会怎么样呢? 

... 
<SimpleConfiguration> 
<EmailInfo> 
<from>support@johhdoeinc.com 
<subject>Your order is ready. Order number {0}</subject> 
<body> <![CDATA 
<html> 
<body> 
<p>Here are your order details</p> 
{0} 
</body> 
</html> 
]> 
</body> 
<format>html</format> 
</EmailInfo> 
</SimpleConfiguration> 


只要此配置适当,就可以将先前的方法更改为下面所示的方法: 

public static trivialMailExampleEnabledForConfig(string toCustomer, string 
orderId) 
{ 
string from = AppServices.getvalue("/SimpleConfiguration/from"); 
// an error not to have it 
string subject = 
string.format(AppServices.getvalue("/SimpleConfiguration/from"), orderId); 
string body = 
string.format(AppServices.getvalue("/SimpleConfiguration/from"), orderId); 
string format = 
AppServices.getvalue("/SimpleConfiguration/from","plain-text"); 
// defaults to plain-text 
sendMail(from,toCustomer,subject,body,format); 
}  
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -