存储配置信息的位置

时间:2009-02-23 14:24:13

标签: c# .net configuration

我有一个控制台应用程序,我正在从C重建为C#。该应用程序必须能够支持存储信息的传统方法,例如来自命令行的参数和来自定制每次运行的文件(称为系统参数)的参数。系统参数文件是纯文本的,带有一个简单的键:值结构。

我的问题是:

  • 我应该将这些不同的参数合并到一个Configuration对象中吗?
  • 如何从存储参数的代码中调用此配置对象?
  • 如何从代码中调用此配置对象来检索参数?
    • 这个对象应该是强类型的吗?
  • 我需要从代码中的很多不同位置访问这个结构,在没有将对象本身传递到任何地方的情况下,检索对象中的值的最优雅方法是什么?

我觉得它应该是一个强类型的单一对象,它应该是一个实例化的对象,它是使用静态检索方法从存储库中检索的,但是我真的想要验证这个方法。

提前致谢

4 个答案:

答案 0 :(得分:7)

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

  

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

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

答案 1 :(得分:7)

我会使用如下的单个配置对象:

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 + "'");
      }
  }
}

由于这是singleton,因此第一次从public static对象引用Setting属性时,它将创建一个且只有一个实例。

创建对象时,它从Settings.ini文件中读取。设置文件是一个纯文本文件,其结构简单key : value,如下所示:

FrameMax : 12
VideoDir : C:\Videos\Best

该对象使用反射来发现每个属性并存储其初始值。在此示例中,已定义了两个属性:

    public static int FrameMax { get; set; }
    public static string VideoDir { get; set; }

代码编写处理Int32String类型。通过向case语句添加其他switch语句,您可以轻松添加对FloatDecimal等类型的支持。

要更改设置,您可以使用以下内容:

Setting.FrameMax = 5;

要检索设置,您可以使用以下内容:

if (Setting.FrameMax > 10) ...

您会注意到所有属性都是强类型的。此外,您不必传递Setting对象,因为所有Setting属性都是static并且始终可用。

我希望这个想法很有用。

答案 2 :(得分:1)

我发现每当我必须处理遗留系统时,坚持使用旧格式几乎总是效果最好。通常有其他人将遗留格式用于其他任务(例如,应用程序的自动化),因此如果您重新编码应用程序处理输入的方式,您可能会破坏其他系统。

另一方面,如果你非常有信心知道所有使用该系统的人,并且他们告诉你他们不关心你是否改变了这些类型的东西,我可能会把所有东西都移到XML上。从应用程序的角度来看,除了XML的所有优点之外(比如ASCII,因此它很容易被人类修改,自我记录等等),XML也节省时间,因为你没有编写自己的I / O或解析器。已经有各种各样的库,特别是在.NET 3.0 / 3.5中,它们做得非常好。 (当你转向C#时,我猜你已经在考虑这些问题了:)

最终,您必须根据实施成本做出决定:如果您通过迁移到XML或类似的方式降低实施成本,请确保不要提高其他人的实施成本转移到新的应用程序框架。

祝你好运!

答案 3 :(得分:0)

XmlDocument - 您可以使用XSD.exe

生成类定义