在哪里存储配置信息?

7
我有一个控制台应用程序,我正在将其从C语言重构为C#语言。这个应用程序必须能够支持存储来自命令行和文件(称为系统参数)的信息的传统方法,并且可以自定义每次运行。系统参数文件是纯文本,具有简单的键值结构。
我的问题如下:
  • 我应该将这些不同的参数合并到一个配置对象中吗?
  • 我该如何从代码中调用此配置对象以存储参数?
  • 我该如何从代码中调用此配置对象以检索参数?
    • 这个对象应该是强类型的吗?
  • 我需要从代码中的许多不同位置访问此结构。在不到处传递对象本身的情况下,最优雅的检索对象中的值的方式是什么?
我有一种感觉,它应该是一个单一的、强类型的对象,并且应该是一个被实例化的对象,通过静态检索方法从存储库中检索,但我真的想验证这种方法。
4个回答

8
我会使用一个单一的配置对象,如下所示:
using System;
using System.IO;
using System.Reflection;
public sealed class Setting {
  public static int FrameMax { get; set; }
  public static string VideoDir { get; set; }
  static readonly string SETTINGS = "Settings.ini";
  static readonly Setting instance = new Setting();
  Setting() {}
  static Setting() {
    string property = "";
    string[] settings = File.ReadAllLines(SETTINGS);
    foreach (string s in settings)
      try {
        string[] split = s.Split(new char[] { ':' }, 2);
        if (split.Length != 2)
          continue;
        property = split[0].Trim();
        string value = split[1].Trim();
        PropertyInfo propInfo = instance.GetType().GetProperty(property);
        switch (propInfo.PropertyType.Name) {
          case "Int32":
            propInfo.SetValue(null, Convert.ToInt32(value), null);
            break;
          case "String":
            propInfo.SetValue(null, value, null);
            break;
        }
      } catch {
        throw new Exception("Invalid setting '" + property + "'");
      }
  }
}

由于这是一个单例模式,因此它将在第一次从Setting对象引用public static属性时创建唯一的实例。

创建对象时,它会从Settings.ini文件中读取内容。设置文件是一个纯文本文件,具有简单的key : value结构,可能看起来像这样:

FrameMax : 12
VideoDir : C:\Videos\Best

该对象使用反射来发现每个属性并存储其初始值。在此示例中,已定义了两个属性:
    public static int FrameMax { get; set; }
    public static string VideoDir { get; set; }

代码目前处理的是Int32String类型。通过在switch语句中添加额外的case语句,您可以轻松添加对FloatDecimal等类型的支持。
要更改设置,您可以使用以下代码:
Setting.FrameMax = 5;

要检索设置,您可以使用以下方式:

if (Setting.FrameMax > 10) ...

你会注意到所有属性都是强类型的。此外,你不需要传递Setting对象,因为所有的Setting属性都是静态的,并且随时在任何地方可用。
我希望这个想法对你有所帮助。

1
这似乎无法将设置更改持久化到文件中...例如,Setting.MyValue = 19 不会将其保存到 Settings.ini 文件中。 - bulltorious
版本控制怎么办(最简单的情况是添加一个新的配置项)?如果使用旧版本应用程序创建的配置文件,会出现问题吗? - Peter Mortensen

7
我喜欢使用设置。这些可以通过使用添加新文件对话框创建设置文件或从项目属性中添加默认设置文件来自动生成。
每个设置可能在用户或应用程序范围内,控制用户是否可以更改它们或者它们被限制为默认值。它们可以通过Save()方法轻松保存,并自动加载到静态Default属性中。

这个类似乎是应用程序或基于用户的设置。我正在寻找每次运行的设置。在这种情况下,你仍然会推荐使用这个类吗?- x97mdr

是的。如果您既有基于用户/应用程序的设置,又有每次运行的设置,您应该使用两个不同的类 - 正常(已保存)的设置和每次运行的设置。
只要不保存每次运行的设置,您就应该是安全的,并且设置仍然很容易使用。这些是静态设置。如果相同的应用程序运行需要多个实例 - 这是错误的方法。

这个类似乎是用于应用程序或用户设置的。我正在寻找每次运行的设置。在这种情况下,您仍然建议使用这个类吗? - Jeffrey Cameron

1

我发现每当我需要处理一个遗留系统时,坚持使用旧格式几乎总是最好的选择。通常情况下,其他人也在使用遗留格式进行其他任务(例如应用程序的自动化),因此如果您重新编码应用程序处理输入的方式,则可能会破坏其他系统。

另一方面,如果您相当有信心知道所有使用该系统的人,并且他们告诉您他们不在意您更改这些类型的事情,那么我可能会将所有内容移动到XML。除了从应用程序角度来看XML的所有不错功能(例如以ASCII形式存在,易于人类修改,自文档化等),XML还可以节省时间,因为您不必编写自己的I/O或解析器。已经有各种各样的库存在,特别是在.NET 3.0 / 3.5中,它们做得非常好。(由于您正在转向C#,我猜想您已经考虑过这些问题:)

因此,最终,您必须基于实施成本来做出决策:如果通过移动到XML或类似技术降低了您的实施成本,请确保不会提高其他人的实施成本以移动到您的新应用程序框架。

祝你好运!


我现在必须支持旧格式。不过,将来我想转移到XML。您认为上述的Settings类怎么样? - Jeffrey Cameron
但是你如何处理版本控制?最简单的方法是添加一个新的配置设置。 - Peter Mortensen

0

XmlDocument - 你可以使用XSD.exe生成一个类定义。


但是你如何处理版本控制?最简单的方法是添加一个新的配置设置。 - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接