Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 来自名称-值对的配置对象_.net_Design Patterns_Architecture_Configuration_Name Value - Fatal编程技术网

.net 来自名称-值对的配置对象

.net 来自名称-值对的配置对象,.net,design-patterns,architecture,configuration,name-value,.net,Design Patterns,Architecture,Configuration,Name Value,我正在开发一个需要在数据库中存储和更新配置的web应用程序。例如,我可能会存储用户首选项,如默认颜色、语言、首选日期格式等 数据库表由名称/值对(NVARCHAR)组成。很简单 我使用ORM获取这些名称/值字符串对的列表(实际上是IEnumerable)。我的问题是,我需要将这些IEnumerable转换为比名称/值字符串更具表现力的内容。也就是说,我想创建一个强类型配置对象 理想情况下,我希望使这个配置对象不直接依赖于ORM,但我不确定如何进行,因为这个对象的初始化和用户首选项的持久性需要通过

我正在开发一个需要在数据库中存储和更新配置的web应用程序。例如,我可能会存储用户首选项,如默认颜色、语言、首选日期格式等

数据库表由名称/值对(NVARCHAR)组成。很简单

我使用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,而无需付出太多努力。但是,如何获取和持久化全局设置?也就是说,在我的应用程序中的某个地方,我希望获得全局设置的实例

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)中,或者最坏的情况放在应用层中