我正在开发一个需要在数据库中存储和更新配置的网络应用程序。例如,我可能会存储用户偏好,如默认颜色、语言、首选日期格式等。
数据库表由名称/值对 (nvarchars) 组成。很简单。
我正在使用 ORM 来获取这些名称/值字符串对的列表(实际上是 IEnumerable)。我的问题是我需要将这些 IEnumerable 转换为比名称/值字符串更具表现力的东西。也就是说,我想做一个强类型的配置对象。
理想情况下,我想让这个配置对象不直接依赖于 ORM,但我不确定如何去做,因为这个对象的初始化和用户偏好的持久性需要通过ORM。
某种设计模式来拯救?
(没关系,但我使用的是 C# 和实体框架。)
编辑:
假设我的域对象中有以下字段:
public class SettingNameValuePair {
public string Name {get;set;}
public string Value {get;set;}
}
public class GlobalSettings {
public System.Drawing.Color FontColor {get;set;}
public TimeZoneInfo DefaultTimeZone {get;set;}
public DateTime DateCreated {get;set;}
... constructor ...
... validation, other functions ...
}
我可以毫不费力地设置我的 ORM 来获取和持久化 SettingNameValuePair。但是,我如何获取和持久化 GlobalSettings?也就是说,在我的应用程序的某个地方,我想获得一个全局设置的实例。
using (var context = new ApplicationContext()) {
GlobalSettings settings = ???
}
当然,ORM 不知道如何在 SettingNameValuePair 和 GlobalSettings 之间自动转换。我知道我需要编写一些“管道”代码来生成 GlobalSettings 的强类型属性。
我的问题是:什么是取回由 SettingNameValuePair 填充的 GlobalSettings 实例的好方法?这里有两个选项肯定是错误的:
1) 让 GlobalSettings 的构造函数将数据上下文作为参数。这引入了不良的依赖性并且难以测试。
2) 让 GlobalSettings 的构造函数从数据上下文中获取 SettingNameValuePair,如下所示:
using (var context = new ApplicationContext()) {
IEnumerable<SettingNameValuePair> nameValuePairs =
context.NameValuePairs.ToList();
GlobalSettings settings = new GlobalSettings(nameValuePairs);
}
这样做的问题是您必须在所有地方重复此代码。
我觉得有更好的解决方案涉及单例、静态类、代理或工厂方法,但我对这些概念还不满意。