3

我目前正在扩展一些利用查找表的现有代码。现在这个表大约有 25 个条目,无论好坏,键/值都存储在 web.conf 的 appsettings 部分。它们被读入字典并在整个应用程序中使用。

我会将查找表的大小增加到大约 300 个条目,这是该域的完整值集 - 因此它不太可能变得更大也不太可能频繁更改。我不确定将这些数据保存在 web.conf 中是否是个好主意。数据库不是此实现的选项,因此我正在寻找另一种存储此数据的方法。我的一些想法是:

  • 静态字典?
  • XML 文件(或其他一些平面外部数据文件)
  • 将它留在 web.conf 的 appsettings 部分?

我倾向于在一个包含操作数据集的方法的类中填充一个静态字典。任何建议、评论或愤怒的呼喊都将不胜感激。

4

4 回答 4

7

您可以将附加的键值对存储在通过 appSettings 元素引用的配置文件中 - 这使您的主配置文件保持整洁,并将附加配置存储在它自己的依赖配置文件中。

这在文章MSDN - appSettings Element (General Settings Schema)中有解释。

这实际上是您的第二项和第三项的组合。

出于维护原因,我不会将它放在代码内的静态字典中 - 配置文件也是此数据的更明显位置。通过利用内置的 .Net 功能,您也不会冒其他人忽略 Xml 文件的风险。

一个更具体的例子是(注意文件路径是相对于主应用程序的):

应用程序配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   

   <appSettings file="mykeyvaluepairs.config"/>

</configuration> 

mykeyvaluepairs.config

<?xml version="1.0" encoding="utf-8" ?>
<appSettings>

  <add key="imaginativelynamedkey1" value="imaginativelynamedvalue1" />

</appSettings>

请注意,在您的原始 app.config 中,也可以执行以下操作:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   

   <appSettings file="mykeyvaluepairs.config">
       <add key="CanBeOverridenByItemInChildConfigFileWithSameName" value="UnicornsGoHere" />
   </appSettings>

</configuration> 

也就是说,除非您在 mykeyvaluepairs.config 文件中重新定义 appsettings,否则两者将并排存在 - 但 mykeyvaluepairs.config 中具有相同名称的项目将覆盖主配置中的值。

于 2012-05-01T16:19:06.323 回答
0

如果您要求封装,最好的方法是公开一个接口,该接口将返回您想要的值,然后注入具体实现。多亏了这一点,您可以轻松地更改实现。

在实施时,如果数据永远不会更改或更改是为了下一个版本(基本上,如果只有开发人员可以进行更改)我会选择底层字典(并将其配置为 DI 容器中的单例)。更重要的是,我会将键保留为枚举值,以提供额外的类型安全性。恕我直言,如果管理员或业务用户无法配置某些内容,则将其保留在外部配置中只会增加不必要的复杂性。

于 2012-05-01T16:21:19.333 回答
0

这是给您的 XML 文件示例。您可以像这样利用它:

string value = MyConfig.Items[key];

要为其添加新值:

MyConfig.Write(file => file.Add("newKey", "newValue"));

班上:

public class MyConfig : IDisposable
{
    string file = "path to file";  // probably in App_Data if this is asp.net
    XElement self;

    public MyConfig()
    {
        if(File.Exists(file))
            self = XElement.Load(file);
        else
            self = new XElement("root");
    }

    public void Add(string key, string value)
    {
        if (!Items.ContainsKey(key))
        {
            self.Add(new XElement("pair",
                new XAttribute("Key", key),
                new XAttribute("Value", value)));
            _Items = null;
        }
    }

    public void Dispose()
    {
        self.Save(file);
    }

    public static Dictionary<string, string> Items
    {
        get
        {
            if (null == _Items)
            {
                _Items = Read.self.Elements().ToDictionary(
                    x => x.Attribute("Key").Value,
                    x => x.Attribute("Value").Value);
            }
            return _Items;
        }
    }
    static Dictionary<string, string> _Items;

    public static MyConfig Read { get { return new MyConfig(); } }
    public static void Write(Action<MyConfig> action)
    {
        using (MyConfig config = new MyConfig())
            action(config);
    }
}

由于网站是多线程的,因此您可能希望在分配/读取 _Items 变量时锁定它。

于 2012-05-01T16:44:53.147 回答
0

Dictionary是处理代码中的键/值信息的好选择。最好保持配置文件简洁明了,因此不要将所有 300 个键和值都放在那里。您可以使用 XML 序列化在单独的 XML 文件中轻松存储(和加载)大量或大量自定义设置。看起来很适合你的情况。

使用此示例代码将数据保存到 XML 或从 XML 加载数据。

public class KeyValue
{
    public string Key;
    public string Value;
}

static void Save()
{
    // some test data
    Dictionary<string, string> dict = new Dictionary<string, string>();
    dict.Add("key1", "value1");
    dict.Add("key2", "value2");
    dict.Add("key3", "value3");
    dict.Add("key4", "value4");

    // convert to List
    List<KeyValue> list1 = (from itm in dict
                            select new KeyValue
                                       {
                                           Key = itm.Key, Value = itm.Value
                                       }).ToList();

    // serialize
    using (StreamWriter sw = new StreamWriter("C:\\temp\\config.xml"))
    {
        XmlSerializer xs = new XmlSerializer(typeof (List<KeyValue>));
        xs.Serialize(sw, list1);
        sw.Close();
    }
}

static void Load()
{
    // deserialize
    using (StreamReader sr = new StreamReader("c:\\temp\\config.xml"))
    {
        XmlSerializer xs = new XmlSerializer(typeof (List<KeyValue>));
        List<KeyValue> list2 = (List<KeyValue>) xs.Deserialize(sr);
        sr.Close();
    }

    // convert to Dictionary
    Dictionary<string, string> dict2 = list2.ToDictionary(x => x.Key, x => x.Value);
}

注意:您需要KeyValue帮助类,因为其结果dict.ToList()没有List<KeyValuePair<string,string>>正确序列化。

于 2012-05-03T13:10:08.543 回答