在很多.net开发的项目中,我们几乎都会使用到一些自定义的参数,比如说第三方的配置参数之类的.

他们的特点是:1.系统全局 2,可以做成键值对(Dictionary).

我们可以将这些参数放到Web.config,xml或者数据库表中,当然部分不常变的可以直接写在程序中.

为了方便我通常喜欢将他们统放在一个配置管理器中,然后希望别人使用时, 可以像使用AppSetings中的参数一样

初看起来还是比较容易实现,在ConfiguratonManager中定义一个公开属性AppSettings就好了.

实现如下:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ConfigManager
{
public class ConfigurationContainer
{
private static ConfigurationContainer m_Instance = null; public static ConfigurationContainer Instance
{
get
{
if (m_Instance == null)
m_Instance = new ConfigurationContainer();
return m_Instance;
}
} private ConfigurationContainer()
{ } private ReadOnlyDictionary<string, string> _configuration;
private Dictionary<string, string> _mutableConfiguration; public ReadOnlyDictionary<string, string> Configuration
{
get
{
//TODO:check is newest or not in database??
if (_mutableConfiguration == null)
Init(); _configuration =
new ReadOnlyDictionary<string, string>(_mutableConfiguration);
return _configuration;
}
} public bool Add(string key, string value)
{
bool bRet = false;
if (!_mutableConfiguration.ContainsKey(key))
{
_mutableConfiguration.Add(key, value);
bRet = true;
}
return bRet;
} public bool Update(string key, string value)
{
bool bRet = false;
if (_mutableConfiguration.ContainsKey(key))
{
_mutableConfiguration[key] = value;
bRet = true;
}
return bRet;
} public bool Remove(string key)
{
bool bRet = false;
if (_mutableConfiguration.ContainsKey(key))
{
_mutableConfiguration.Remove(key);
bRet = true;
}
return bRet;
} //private bool ConfigurationAllowed(string key, string value)
//{
// // Put in your checks and balances
// // here and return the appropriate result
// return true;
//} private void Init()
{
_mutableConfiguration = new Dictionary<string, string>();
_mutableConfiguration.Add("key", "value");
_mutableConfiguration.Add("key1", "value1");
_mutableConfiguration["key2"] = "value2";
}
}
}
ConfigurationContainer:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ConfigManager
{
public class ConfigManager
{
private static IReadOnlyDictionary<string, string> _AppSettings = null;
public static IReadOnlyDictionary<string, string> Appettings
{
get
{
//initial ensurer the newest
_AppSettings = ConfigurationContainer.Instance.Configuration;
return _AppSettings;
}
} //Exception:Violence to Add
public static void BeNaughtyWithConfiguration()
{
IDictionary<string, string> convertToReadWrite
= (IDictionary<string, string>)_AppSettings;
//ConfigElement element = convertToReadWrite["key"];
//element.Value = "Haa Haa";
//Console.WriteLine(element.Value);
//Console.WriteLine(convertToReadWrite["key"]);
//Console.ReadLine(); convertToReadWrite.Add("Key12345", "xsds");
} public static bool Add(string key, string value)
{
return ConfigurationContainer.Instance.Add(key, value);
} public static bool Update(string key, string value)
{
return ConfigurationContainer.Instance.Update(key, value);
} public static bool Remove(string key)
{
return ConfigurationContainer.Instance.Remove(key);
}
}
}

最底层是一个单例模式,并封装了字典的CRUD操作。

客户端测试一下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ConfigManager
{
class Program
{
static void Main(string[] args)
{
var settings = ConfigManager.Appettings; foreach(var item in settings)
{
Console.WriteLine("key:{0},value:{1}",item.Key,item.Value);
} var t1 = ConfigManager.Appettings["key1"]; //test add
ConfigManager.Add("t","test");
//var t2 = ConfigManager.Appettings;
//update
ConfigManager.Update("t","test123"); //remove
ConfigManager.Remove("t"); Console.ReadKey();
}
}
}

好像也能运行。

那么,问题来了!测试代码改一改,

//test not item in Dictionary
var t2 = ConfigManager.Appettings["luckyhu"];

代码崩溃了,老兄!

其实上面的代码能够满足一般的需求,但是对使用着来说,仍然不太方便.所以我和同事进一步优化了上述代码.

现在变得更加简洁了.

public class SettingManager : Dictionary<string, string>
{
private static SettingManager _Settings = null;
public static SettingManager Settings
{
get
{
if (_Settings == null)
_Settings = new SettingManager();
return _Settings;
}
} private SettingManager()
{
//Init Data
//DataSoure:truely data here...
for (int i = ; i < ; i++)
{
var key = String.Format("key{0}", i);
var value = String.Format("value{0}", i);
if (!this.Keys.Contains(key))
this.Add(key, value);
}
} public string this[string key]
{
get
{
if (!this.ContainsKey(key))
return String.Empty;
return base[key];
}
set
{
base[key] = value;
}
} public static bool GetBoolValue(string key)
{
bool value = false;
bool.TryParse(Settings[key], out value);
return value;
} public static int GetIntValue(string key)
{
int value = ;
int.TryParse(Settings[key], out value);
return value;
}
}

大家看到代码简洁了不少,有了以下改进:

1.代码变少了

2.可以控制索引的返回结果了

3.更多的利用了Dictionary自身的特性,如CRUD

4.增加了自定义类型转换方法

总之,这些努力都是为了方便别人使用.

好吧,看看客户端测试吧

测试结果是OK的

好了,这样一个通用的配置管理器完成了, 当然有更多的需求,还可以对其进行扩展。欢迎大家不吝赐教 .

祝大家新年快乐,万事如意! 2015,一起任性!

一个简单的配置管理器(SettingManager)的更多相关文章

  1. python使用tcp实现一个简单的下载器

    上一篇中介绍了tcp的流程,本篇通过写一个简单的文件下载器程序来巩固之前学的知识. 文件下载器的流程如下: 客户端: 输入目标服务器的ip和port 输入要下载文件的名称 从服务器下载文件保存到本地 ...

  2. 自己写的一个简单PHP采集器

    自己写的一个简单PHP采集器 <?php //**************************************************************** $url = &q ...

  3. [SimplePlayer] 实现一个简单的播放器

    简单的播放器需要实现一个最基本的功能:播放视频文件. 实现这个功能需要包含以下几个步骤: 从视频文件中提取视频图像 在屏幕上显示视频图像 视频帧的同步,也就是保证视频图像在合适的时间在屏幕上显示 从视 ...

  4. C++写一个简单的解析器(分析C语言)

    该方案实现了一个分析C语言的词法分析+解析. 注意: 1.简单语法,部分秕.它可以在本文法的基础上进行扩展,此过程使用自上而下LL(1)语法. 2.自己主动能达到求First 集和 Follow 集. ...

  5. 第二十四篇-用VideoView制作一个简单的视频播放器

    使用VideoView播放视频,视频路径有三种: 1. SD卡中 2. Android的资源文件中 3. 网络视频 第一种,SD卡中的方法. 路径写绝对路径,如果不能播放,可以赋予读取权限. 效果图: ...

  6. Android开发6:Service的使用(简单音乐播放器的实现)

    前言 啦啦啦~各位好久不见啦~博主最近比较忙,而且最近一次实验也是刚刚结束~ 好了不废话了,直接进入我们这次的内容~ 在这篇博文里我们将学习Service(服务)的相关知识,学会使用 Service ...

  7. iOS之基于FreeStreamer的简单音乐播放器(模仿QQ音乐)

    代码地址如下:http://www.demodashi.com/demo/11944.html 天道酬勤 前言 作为一名iOS开发者,每当使用APP的时候,总难免会情不自禁的去想想,这个怎么做的?该怎 ...

  8. AVPlayer的使用+简单的播放器Demo

    学习内容 AVPlayer学习 几个播放器相关的类 AVPlayer.AVURLAsset.AVPlayerItem.AVPlayerLayer //控制播放器的播放.暂停.播放速度 @propert ...

  9. 【模块化编程】理解requireJS-实现一个简单的模块加载器

    在前文中我们不止一次强调过模块化编程的重要性,以及其可以解决的问题: ① 解决单文件变量命名冲突问题 ② 解决前端多人协作问题 ③ 解决文件依赖问题 ④ 按需加载(这个说法其实很假了) ⑤ ..... ...

随机推荐

  1. 初学微信小程序

    最近微信推出了微信小程序,为此我学了几天,基本了解了组件及简单语法,但是今天我自己想要独立写一个demo时,忽然发现难道我的不是微信小程序的语法(我以前是iOS 开发,不用css),而是css样式的设 ...

  2. android控件 ToggleButton的应用

    ToggleButton是android给我们提供的开关按钮, 有两种状态:选中和未选择状态. 以下是代码实例: main.xml [html] view plain copy <?xml ve ...

  3. 2015年ACM长春网络赛(准备做掉7道:已经更新到6道)

    总结汇总:模板 int getmax_min(char s[]) {//字符串的最大表示法:返回最小数组下标 , j = , k = ; while(i < len && j & ...

  4. java基础-泛型1

    浏览以下内容前,请点击并阅读 声明 泛型的使用能使类型名称作为类或者接口定义中的参数,就像一般的参数一样,使得定义的类型通用性更强. 泛型的优势: 编译具有严格的类型检查 java编译器对于泛型代码的 ...

  5. Python2 连接MySQL

    先安装MySQL-python yum install -y MySQL-python 测试代码: # -*- coding: utf-8 -*- import os import MySQLdb i ...

  6. [Leetcode] Roman to Integer

    Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 t ...

  7. CI框架如何在主目录application目录之外使用uploadify上传插件和bootstrap前端框架:

    19:29 2016/3/10CI框架如何在主目录application目录之外使用uploadify上传插件和bootstrap前端框架:项目主路径:F:\wamp\www\graduationPr ...

  8. SpringMVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

  9. Web开发流程

    知乎上关于Web开发流程豪情给予的回答 web前端开发流程是什么?进行操作会用到哪些便捷的小工具?是先用模板做好,然后在基础上改吗??正常大家说的改框架是不是指的用模板做的网站原文件?前端开发做的文件 ...

  10. HTML 5 拖放(Drag 和drop)

    浏览器支持 Internet Explorer 9.Firefox.Opera 12.Chrome 以及 Safari 5. 1.把标签 draggable 属性设置为 true. 2.向标签添加on ...