.net 来自名称-值对的配置对象
我正在开发一个需要在数据库中存储和更新配置的web应用程序。例如,我可能会存储用户首选项,如默认颜色、语言、首选日期格式等 数据库表由名称/值对(NVARCHAR)组成。很简单 我使用ORM获取这些名称/值字符串对的列表(实际上是IEnumerable)。我的问题是,我需要将这些IEnumerable转换为比名称/值字符串更具表现力的内容。也就是说,我想创建一个强类型配置对象 理想情况下,我希望使这个配置对象不直接依赖于ORM,但我不确定如何进行,因为这个对象的初始化和用户首选项的持久性需要通过ORM 什么样的设计模式来拯救 (这不重要,但我使用的是C#和实体框架。).net 来自名称-值对的配置对象,.net,design-patterns,architecture,configuration,name-value,.net,Design Patterns,Architecture,Configuration,Name Value,我正在开发一个需要在数据库中存储和更新配置的web应用程序。例如,我可能会存储用户首选项,如默认颜色、语言、首选日期格式等 数据库表由名称/值对(NVARCHAR)组成。很简单 我使用ORM获取这些名称/值字符串对的列表(实际上是IEnumerable)。我的问题是,我需要将这些IEnumerable转换为比名称/值字符串更具表现力的内容。也就是说,我想创建一个强类型配置对象 理想情况下,我希望使这个配置对象不直接依赖于ORM,但我不确定如何进行,因为这个对象的初始化和用户首选项的持久性需要通过
编辑: 假设我的域对象中有以下字段:
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,而无需付出太多努力。但是,如何获取和持久化全局设置?也就是说,在我的应用程序中的某个地方,我希望获得全局设置的实例
using (var context = new ApplicationContext()) {
GlobalSettings settings = ???
}
当然,ORM不知道如何在SettingNameValuePair和GlobalSettings之间自动转换。我知道我需要编写一些“管道”代码来生成GlobalSettings的强类型属性
using (var context = new ApplicationContext()) {
GlobalSettings settings = ???
}
我的问题是:返回由SettingNameValuePair填充的GlobalSettings实例的好方法是什么?这里有两种选择肯定是错误的:
1) 让GlobalSettings的构造函数将数据上下文作为参数。这引入了一个不好的依赖性,并且很难测试
2) 让GlobalSettings的构造函数从数据上下文中获取SettingNameValuePair,如下所示:
using (var context = new ApplicationContext()) {
IEnumerable<SettingNameValuePair> nameValuePairs =
context.NameValuePairs.ToList();
GlobalSettings settings = new GlobalSettings(nameValuePairs);
}
使用(var context=new ApplicationContext()){
IEnumerable nameValuePairs=
context.NameValuePairs.ToList();
GlobalSettings设置=新的GlobalSettings(nameValuePairs);
}
问题是你必须到处重复这段代码
我觉得有更好的解决方案涉及单例、静态类、代理或工厂方法,但我对这些概念还不太熟悉。我认为没有任何ORM映射到键值对。事实上,对这些数据使用DataReader可能更有效。无论您如何获得数据,您都可以简单地使用配置KVP构建一个字典,然后使用进行访问。然后,您可以为您知道需要的属性创建强类型访问器。这将允许您对所知道的属性使用强类型对象,同时仍然保持在不更改代码的情况下添加属性的灵活性 不要在域对象中引用您的ORM,而是在存储库中实现它,存储库将利用您的ORM或任何数据访问技术(例如,数据读取器,因为大多数ORM将无法在键值对和强类型对象之间映射) 此外,我不建议在构造函数中为实体(globalsettings)提供键值对,因为它与域无关。请将键值对映射到域对象,而是在映射器层(即存储库或dal)中实现映射 例如: 在应用层
public GlobalSettings GetUserSettings(User user)
{
return _globalSettingsRepository.GetGlobalSettings(user);
}
在存储库层中
public GlobalSettings GetGlobalSettings(User user)
{
var keyvalue = _context.blablabla();
var globalSettings = new GlobalSettings { Id = keyvalue["key"], DateCreated = DateTime.Parse(keyvalue["datecreated"]) };
return globalSettings
}
你所说的“我想让这个配置对象不直接依赖于ORM”是什么意思?域实体不应该依赖于ORM,而应该由映射层(ORM)填充域实体database@MohamedAbed-我添加了示例代码来演示这个问题。这是一篇很长的文章,我不确定这是否与我的问题有关。我添加了一些示例代码来演示我要做的事情。不过,这篇文章看起来很酷!啊。由于各种原因,我们没有存储库。有没有其他地方可以把这个逻辑放在数据访问对象(DAO)中,或者最坏的情况放在应用层中