[CLK Framework] CLK.Settings - 跨平台的参数存取模块
[CLK Framework] CLK.Settings - 跨平台的参数存取模块
问题情景
开发功能模块的时候,常常免不了有一些参数(例如ConnectionString),需要存放在Config檔(App.Config、Web.Config)。而.NET Framework也很贴心的提供System.Configuration命名空间里的类别,用来帮助开发人员简化存取Config档的开发工作。但是当功能模块的开发,是以跨平台执行为目标来做设计的时候,因为不是每个平台都允许Config档的存在,所以连带的System.Configuration命名空间里的类别,也并不支持跨平台的参考使用。
像是开启一个可携式类别库项目(Portable Class Library),来设计横跨ASP.NET、Windows Phone两个平台的功能模块时,因为Windows Phone平台不支持Config档的存在,所以开发时无法在项目中加入System.Configuration命名空间的参考,用来存取Config档内的参数设定。
遇到这样跨平台的功能模块开发,该如何处理跨平台的参数存取呢?

解决方案
首先,不是每个平台都允许Config档的存在,每个平台各自拥有平台自己的参数存取功能,像是Windows Phone平台不允许的Config档的存在,但是可以透过操作IsolatedStorage来提供参数存取功能。为了切割与这些平台参数存取功能的相依性,可以套用IoC模式在功能模块上,用以建立一层参数存取接口,让跨平台功能模块单纯相依于同模块内的参数存取界面。接着再套用Adapter模式建立转接对象,来将每个平台的参数存取功能,转接成为参数存取接口的实作。这样后续就可以依照执行平台的不同,为跨平台功能模块注入不同的参数存取接口实作,用以提供不同平台上参数存取的功能。

假设,开发一个跨平台功能模块,就要对应开发一个套用Adapter模式的转接对象,来将每个平台的参数存取功能转接成为参数存取接口的实作。这样的开发流程在遇到跨平台功能模块越来越多的情况下,会发现需要开发的转接对象数量会迅速膨胀,进而成为开发人员工作上的负担。

为了简化转接对象的开发工作,可以将参数存取功能抽象化之后,建立成为一个共享的参数存取模块,并且这个共享参数存取模块同样透过套用IoC模式,来切割与平台参数存取功能之间的相依性,让这个共享参数存取模块可以跨平台使用。后续只需要为每个平台专有的参数存取功能,开发一个转接进共享参数存取模块的转接对象,就能让每个使用共享参数存取模块的跨平台功能模块,能够透过平台的参数存取功能来存取参数设定。

模块设计
CLK.Settings是一个跨平台的参数存取模块。在开发跨平台功能模块时,使用CLK.Settings能够帮助开发人员,简化参数存取功能的开发工作。
模块下载
程序代码下载:由此进入GitHub后,点选右下角的「Download ZIP」按钮下载。
(开启程序代码的时候,建议使用Visual Studio所提供的「大纲->折迭至定义」功能来折迭程序代码,以能得到较适合阅读的排版样式。)
对象结构

SettingContext
CLK.Settings模块的根节点对象。
提供Locator功能(选用)。
SettingDictionary
将ISettingRepository接口所提供的CRUD功能,转接为简单使用的Dictionary对象样式提供开发人员使用。
继承自CLK.Collections.StoreDictionary
ISettingRepository
套用IoC模式产生的边界接口。
用来隔离系统与不同平台参数存取功能之间的相依性。
提供参数数据进出模块边界的CRUD功能。
继承自CLK.Collections.IStoreProvider
ConfigConnectionStringRepository
继承ISettingRepository界面。
转接Config文件的联机字符串存取功能,用以提供系统来存取Config文件中的联机字符串设定。
ConfigAppSettingRepository
继承ISettingRepository界面。
转接Config文件的AppSetting存取功能,用以提供系统来存取Config文件中的AppSetting设定。
MemorySettingRepository
继承ISettingRepository界面。
在内存中建立一个参数集合对象来存放参数设定,用以提供系统来存取内存中的参数设定。
对象互动
读取参数

列举参数

新增参数

移除参数

使用范例
No001 - 建立模块
在使用SettingContext对象之前,必须先取得系统所使用的SettingContext对象,在本篇中统一透过生成函式来提供SettingContext对象。例如下列范例中的生成函式,会建立一个SettingContext对象的子类别:ConfigSettingContext对象,这个ConfigSettingContext对象会转接Config文件的参数存取功能,用以提供系统来存取Config文件中的参数设定。
建立模块
static SettingContext Create()
{
// SettingContext
SettingContext settingContext = new ConfigSettingContext(); // Return
return settingContext;
}
No002 - 读取参数
建立模块
static SettingContext Create()
{
// SettingContext
SettingContext settingContext = new ConfigSettingContext(); // Return
return settingContext;
}
配置文件
<!--AppSettings-->
<appSettings>
<add key="Argument01" value="AAAAAAAAAAAAA" />
<add key="Argument02" value="BBBBBBBBBBBBB" />
<add key="Argument03" value="CCCCCCCCCCCCC" />
</appSettings> <!--ConnectionStrings-->
<connectionStrings>
<clear/>
<add name="Database01" connectionString="Data Source=192.168.1.1;Initial Catalog=DB01;" />
<add name="Database02" connectionString="Data Source=192.168.2.2;Initial Catalog=DB02;" />
</connectionStrings>
读取参数
static void Main(string[] args)
{
// Create
SettingContext settingContext = Program.Create(); // Get
Console.WriteLine("\nAppSettings");
string argumentString = settingContext.AppSettings["Argument01"];
Console.WriteLine(argumentString); Console.WriteLine("\nConnectionStrings");
string connectionString = settingContext.ConnectionStrings["Database01"];
Console.WriteLine(connectionString); // End
Console.WriteLine("\nPress enter to end...");
Console.ReadLine();
}
执行结果

No003 - 列举参数
建立模块
static SettingContext Create()
{
// SettingContext
SettingContext settingContext = new ConfigSettingContext(); // Return
return settingContext;
}
配置文件
<!--AppSettings-->
<appSettings>
<add key="Argument01" value="AAAAAAAAAAAAA" />
<add key="Argument02" value="BBBBBBBBBBBBB" />
<add key="Argument03" value="CCCCCCCCCCCCC" />
</appSettings> <!--ConnectionStrings-->
<connectionStrings>
<clear/>
<add name="Database01" connectionString="Data Source=192.168.1.1;Initial Catalog=DB01;" />
<add name="Database02" connectionString="Data Source=192.168.2.2;Initial Catalog=DB02;" />
</connectionStrings>
列举参数
static void Main(string[] args)
{
// Create
SettingContext settingContext = Program.Create(); // List
Console.WriteLine("\nAppSettings");
foreach (string key in settingContext.AppSettings.Keys)
{
string argumentString = settingContext.AppSettings[key];
Console.WriteLine(argumentString);
} Console.WriteLine("\nConnectionStrings");
foreach (string key in settingContext.ConnectionStrings.Keys)
{
string connectionString = settingContext.ConnectionStrings[key];
Console.WriteLine(connectionString);
} // End
Console.WriteLine("\nPress enter to end...");
Console.ReadLine();
}
执行结果

No004 - 新增参数
建立模块
static SettingContext Create()
{
// SettingContext
SettingContext settingContext = new ConfigSettingContext(); // Return
return settingContext;
}
原始配置文件
<!--AppSettings-->
<appSettings>
<add key="Argument01" value="AAAAAAAAAAAAA" />
<add key="Argument02" value="BBBBBBBBBBBBB" />
<add key="Argument03" value="CCCCCCCCCCCCC" />
</appSettings> <!--ConnectionStrings-->
<connectionStrings>
<clear/>
<add name="Database01" connectionString="Data Source=192.168.1.1;Initial Catalog=DB01;" />
<add name="Database02" connectionString="Data Source=192.168.2.2;Initial Catalog=DB02;" />
</connectionStrings>
新增参数
static void Main(string[] args)
{
// Create
SettingContext settingContext = Program.Create(); // Set
settingContext.AppSettings.Add("Argument04", "DDDDDDDDDDDDD"); settingContext.ConnectionStrings.Add("Database03", "Data Source=192.168.3.3;Initial Catalog=DB03"); // End
Console.WriteLine("\nPress enter to end...");
Console.ReadLine();
}
结果配置文件
<!--AppSettings-->
<appSettings>
<add key="Argument01" value="AAAAAAAAAAAAA" />
<add key="Argument02" value="BBBBBBBBBBBBB" />
<add key="Argument03" value="CCCCCCCCCCCCC" />
<add key="Argument04" value="DDDDDDDDDDDDD" />
</appSettings> <!--ConnectionStrings-->
<connectionStrings>
<clear />
<add name="Database01" connectionString="Data Source=192.168.1.1;Initial Catalog=DB01;" />
<add name="Database02" connectionString="Data Source=192.168.2.2;Initial Catalog=DB02;" />
<add name="Database03" connectionString="Data Source=192.168.3.3;Initial Catalog=DB03" />
</connectionStrings>
No005 - 移除参数
建立模块
static SettingContext Create()
{
// SettingContext
SettingContext settingContext = new ConfigSettingContext(); // Return
return settingContext;
}
原始配置文件
<!--AppSettings-->
<appSettings>
<add key="Argument01" value="AAAAAAAAAAAAA" />
<add key="Argument02" value="BBBBBBBBBBBBB" />
<add key="Argument03" value="CCCCCCCCCCCCC" />
</appSettings> <!--ConnectionStrings-->
<connectionStrings>
<clear/>
<add name="Database01" connectionString="Data Source=192.168.1.1;Initial Catalog=DB01;" />
<add name="Database02" connectionString="Data Source=192.168.2.2;Initial Catalog=DB02;" />
</connectionStrings>
移除参数
static void Main(string[] args)
{
// Create
SettingContext settingContext = Program.Create(); // Set
settingContext.AppSettings.Remove("Argument03"); settingContext.ConnectionStrings.Remove("Database02"); // End
Console.WriteLine("\nPress enter to end...");
Console.ReadLine();
}
结果配置文件
<!--AppSettings-->
<appSettings>
<add key="Argument01" value="AAAAAAAAAAAAA" />
<add key="Argument02" value="BBBBBBBBBBBBB" />
</appSettings> <!--ConnectionStrings-->
<connectionStrings>
<clear />
<add name="Database01" connectionString="Data Source=192.168.1.1;Initial Catalog=DB01;" />
</connectionStrings>
No006 - 更换来源
只要更换生成函式所提供的SettingContext对象,就可以更换系统所使用的参数设定来源。例如下列范例中的生成函式,改为会建立一个SettingContext对象的子类别:MemorySettingContext对象,这个MemorySettingContext对象,会在内存中建立一个参数集合对象来存放参数设定,用以提供系统来存取内存中的参数设定。
(额外一提,作单元测试的时候,使用MemorySettingContext对象来取代ConfigSettingContext对象,就可以透过程序代码来提供测试用的参数设定,而不需要另外维护Config档来提供测试用的参数设定。)
更换来源
static SettingContext Create()
{
// AppSettingRepository
MemorySettingRepository appSettingRepository = new MemorySettingRepository();
appSettingRepository.Add("Argument05", "XXXXXXXXXXXXX");
appSettingRepository.Add("Argument06", "YYYYYYYYYYYYY");
appSettingRepository.Add("Argument07", "ZZZZZZZZZZZZZ"); // ConnectionStringRepository
MemorySettingRepository connectionStringRepository = new MemorySettingRepository();
connectionStringRepository.Add("Database04", "Data Source=192.168.4.4;Initial Catalog=DB04;");
connectionStringRepository.Add("Database05", "Data Source=192.168.5.5;Initial Catalog=DB05;"); // SettingContext
SettingContext settingContext = new MemorySettingContext(appSettingRepository, connectionStringRepository); // Return
return settingContext;
}
列举参数
static void Main(string[] args)
{
// Create
SettingContext settingContext = Program.Create(); // List
Console.WriteLine("\nAppSettings");
foreach (string key in settingContext.AppSettings.Keys)
{
string argumentString = settingContext.AppSettings[key];
Console.WriteLine(argumentString);
} Console.WriteLine("\nConnectionStrings");
foreach (string key in settingContext.ConnectionStrings.Keys)
{
string connectionString = settingContext.ConnectionStrings[key];
Console.WriteLine(connectionString);
} // End
Console.WriteLine("\nPress enter to end...");
Console.ReadLine();
}
执行结果

[CLK Framework] CLK.Settings - 跨平台的参数存取模块的更多相关文章
- [CLK Framework] CLK.Threading.PortableTimer - 跨平台的Timer类别
[CLK Framework] CLK.Threading.PortableTimer - 跨平台的Timer类别 问题情景 开发应用程式的时候,免不了需要加入一些定时执行的设计,例如说:定时更新画面 ...
- python中处理命令行参数的模块optpars
optpars是python中用来处理命令行参数的模块,可以自动生成程序的帮助信息,功能强大,易于使用,可以方便的生成标准的,符合Unix/Posix 规范的命令行说明.使用 add_option() ...
- python命令行参数解析模块argparse和docopt
http://blog.csdn.net/pipisorry/article/details/53046471 还有其他两个模块实现这一功能,getopt(等同于C语言中的getopt())和弃用的o ...
- LEDAPS1.3.0版本移植到windows平台----HuPm参数初始化模块
这个是2012年左右放在百度空间的,谁知百度空间关闭...转移到博客园. 最近项目用到3.1.2版本的LEDAPS,新版本的使用情况会在后续文章中慢慢丰富. LEDAPS的调用顺序是:HuPm--&g ...
- $命令行参数解析模块argparse的用法
argparse是python内置的命令行参数解析模块,可以用来为程序配置功能丰富的命令行参数,方便使用,本文总结一下其基本用法. 测试脚本 把以下脚本存在argtest.py文件中: # codin ...
- Python命令行参数解析模块getopt使用实例
Python命令行参数解析模块getopt使用实例 这篇文章主要介绍了Python命令行参数解析模块getopt使用实例,本文讲解了使用语法格式.短选项参数实例.长选项参数实例等内容,需要的朋友可以参 ...
- 十分钟使用ionic Framework开发一个跨平台移动应用
Ionic是一个前端的框架,帮助开发人员使用HTML5, CSS3和JavaScript做出原生应用. ionic的理念类似前端开发的BootStrap,目标是封装HTML5移动跨平台开发的最佳实践. ...
- Robot Framework封装的关键字输入参数可以传入多个值的方法
输入参数的最后一个参数可以是一个列表变量,通过@{列表名称}或者${列表名称}的方式实现传入多个值的场景: 或者
- 基于Java+HttpClient+TestNG的接口自动化测试框架(四)-------参数存取处理
在真正开始接口测试之前,我们需要对参数的处理进行梳理.这里所说的“参数”,既包含之前在xml中的配置(我们称之为全局参数),也包含在每一条用例中书写的param.全局参数为固定不变的,而根据接口相应获 ...
随机推荐
- cocos2dx在ubuntu下配置声音引擎
声音引擎库和cocos2dx的库是分开的我们要使用的时候不得不重新修改一下makefile,首先我们要找到声音引擎库的位置,在cocos2dx的 根目录下有一个lib文件,看一下是否存在libcoco ...
- Windows batch,echo到文件不成功,只打印出ECHO is on.
jenkins 执行Windows batch command的时候,如果想要读写文件,echo到文件不成功. bat 代码如下: set ctime=%date%_%time% echo %ctim ...
- 三十一、【WCF路由中间件】WCFHosting服务主机的路由器与负载均衡和实现思路
回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://pan.baid ...
- Android Studio NDK 学习之接受Java传入的Int数组
本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK. 用Android Studio新建一个工程叫AndroidJ ...
- 尝试在virtualbox fedora21 下安装additions和mount share folder
安装这个additions的过程,基本上可以参照 http://gamblisfx.com/how-to-install-virtualbox-guest-additions-on-fedora-21 ...
- WPF中模板选择和DataContext的一些使用
如图样: View结构 MainView(MainViewModel)|---Guide1View(Guide1ViewModel)|---Guide2View(Guide2ViewModel) |- ...
- JS基础回顾,小练习(判断数组,以及函数)
追梦子博客版权所有. // 判断arr是否为一个数组,返回一个bool值 方法1: function isArray(arr) { var str = arr.__proto__.constructo ...
- 伸展树(三)之 Java的实现
概要 前面分别通过C和C++实现了伸展树,本章给出伸展树的Java版本.基本算法和原理都与前两章一样.1. 伸展树的介绍2. 伸展树的Java实现(完整源码)3. 伸展树的Java测试程序 转载请注明 ...
- github神器--Atom编辑器初体验
Atom 1.0正式式版已经出来好几天,自从听说github出了这神器之后,一直想体验一吧,这两天终于体验上. 下载: https://atom.io/ 其实,我的网速还不错,但总是下载到一半就没网速 ...
- Device.js – 快速检测平台、操作系统和方向信息
在 Web 项目中,有时候我们需要根据程序运行的环境采取特定操作.Device.js 是一个很小的 JavaScript 库,它简化了编写和平台,操作系统或浏览器相关的条件 CSS 或 JavaScr ...