为应用程序层创建自定义配置





4.00/5 (2投票s)
本文介绍了创建应用程序层集成自定义配置的酷炫功能。
引言
在 .NET 框架中有几个特性,我们通常会忽略或在我们的业务解决方案中未实现,但这些虽然微小但非常有用的特性,可以使我们的生活变得非常酷。在这些特性中,今天我想讨论强大的自定义配置功能,它使我们能够从单个配置文件中,以清晰、声明式的方式集成我们的应用程序层。
背景
几天前,我正在使用 ASP.NET 2.0、C#、SQL Server 2005 等技术处理一个业务解决方案。这是一个基于工作流的大型企业应用程序。有几个通用(请不要与 .NET Framework 的泛型功能混淆)层负责提供不同类型的服务。这些层应该共享一些通用的配置相关信息(例如:数据库连接字符串、LDAP 连接字符串等等),这些信息声明在 web.config 文件(在 ConnectionStrings
块中)。
现在,问题是如何在各层之间共享这些连接字符串(或各种设置),这样我们就不需要硬编码键名了。
解决方案非常简单,并且内置于 .NET Framework 中。我们只需利用 System.Configuration
,就得到了一个声明式语法,用于从 web.config 文件共享配置。
实现自定义配置
对我来说,并且我相信对所有人来说,通过具体的实现来理解概念总是更好的选择。因此,我想举一个类库项目作为例子,该项目需要集成到一个 Web 应用程序中,并且需要共享一些配置(如数据库连接字符串和 Active Directory 连接字符串)。
为了声明连接字符串,.NET Framework 2.0 在配置文件中有一个非常独特的节:<connectionStrings>
节。假设我们在 <connectionStrings>
节中有两个条目,如下面的代码片段所示
<connectionStrings>
<add name="DBConnection"
connectionString="string to connect database"
providerName="System.Data.SqlClient"/>
<add name="ADConnection"
connectionString="string to connect Active Directory"/>
</connectionStrings>
现在,让我们转到需要这两个连接的类库项目(ASP.NET 应用程序也需要这些连接来实现其内部业务逻辑)。
有两种方法可以实现这些连接字符串的共享:
- 在类库中硬编码键名(
DBConnection
、Adconnection
)。 - 使用声明式语法与类库共享连接字符串键。
第一种选择不太可接受,因为如果键名发生更改,则需要修改类库代码,或者如果它是一个通用的模块(例如可以插入到各种应用程序中的实用模块),那么这将很难实现(与代码中硬编码键名是相同的原因)。但在第二种情况下,我们不需要修改类库的代码,因此在集成和可管理性方面会容易得多。
现在,为了完成这项任务,我们只需要添加一个需要继承自 System.Configuration.ConfigurationSection
的类。
请仔细阅读下面的类声明,以了解这方面的知识
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
namespace CustomSettingsProvider
{
internal class CustomSettings:ConfigurationSection
{
[ConfigurationProperty("DBConnection",IsRequired=true)]
public string DataBaseConnection
{
get
{
return GetDBConnectionString(this["DBConnection"]);
}
set
{
this["DBConnection"] = value;
}
}
[ConfigurationProperty("AdConnectionString", IsRequired = true)]
public string ADConnection
{
get {
return GetADConnectionString(this["AdConnectionString"];
}
set {
this["AdConnectionString"] = value;
}
}
private string GetDBConnectionString(string connectionKey)
{
return ConfigurationManager.ConnectionStrings[connectionKey].ConnectionString;
}
private string GetADConnectionString(string adConnectionKey)
{
return ConfigurationManager.ConnectionStrings[adConnectionKey].ConnectionString;
}
}
}
这个类将由类库内部使用,以消耗将在配置文件中以声明方式完成的配置设置。
现在,我们来讨论上面类中最有趣的部分
ConfigurationProperty 属性
此属性公开需要从任何配置文件进行配置的属性。有相当多的参数可供我们使用,例如默认值、用于验证分配给这些属性的值的正则表达式。
ConfigurationSection 类
此类提供了创建自定义配置节和配置属性的基本框架。此类的一个实例公开了所有可配置属性的集合。
私有方法
这些方法根据配置文件属性属性中提供的键来实际提取连接字符串。
现在,让我们看看类库中的其他类如何使用这些配置属性。为此,我们将通过另一个类实现和配置文件的自定义配置节来了解
public class CustomSettingsConsumer
{
private string _dbConnection;
private string _adConnection;
public string Connection
{
get { return this._dbConnection; }
}
public string ADConnection
{
get { return this._adConnection; }
}
public CustomSettingsConsumer()
{
this._dbConnection = ((CustomSettings)
ConfigurationManager.GetSection("CustomSettings")).DataBaseConnection;
this._adConnection = ((CustomSettings)
ConfigurationManager.GetSection("CustomSettings")).ADConnection;
//some Bll logic
}
}
这是配置文件
<configSections>
<section name="CustomSettings"
type="CustomSettingsProvider.CustomSettings"/>
</configSections>
<CustomSettings DBConnection="DBConnection"
AdConnectionString="ADConnection" />
<section name=""CustomSettings""
type=""CustomSettingsProvider.CustomSettings"">
</customsettings>
<ConfigSections>
包含我们的自定义配置。name
属性的值应与 GetSection
方法的参数值匹配(请参阅上面的使用者代码)。否则,我们将无法为类库提取配置值。type
属性表示继承自 System.Configuration.ConfigurationSection
类的类名。现在,我们来看配置属性的声明式初始化。<CustomSettings>
元素在此处执行初始化。如果您遵循 CustomSettings
类,您将看到有两个自定义配置属性:DBConnection
和 ADConnectionString
。我们通过传递连接字符串键名来实际(以声明方式)初始化此处的值。因此,总集成变得非常容易。
现在,如果您查看 CustomSettingsConsumer
类的构造函数,您会发现获取自定义配置值并使用这些资源实现任何业务逻辑是多么容易。
关注点
在创建解决方案的各个层之后,我们所做的最重要的事情就是集成。 .NET Framework 通过公开 System.Configuration 程序集,使此步骤变得非常容易。有许多潜在的类可供我们深入研究,以使任何应用程序的配置部分变得轻松且符合我们的需求。