Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a console application that I am rebuilding from C to C#. This application has to be able to support the legacy method of storing information like parameters from a command-line and parameters from a file (called the system parameters) that customize each run. The system parameters file is in plain-text with a simple key-value structure.

My questions are:

  • Should I combine these different parameters into a single Configuration object?
  • How would I call this configuration object from the code to store parameters?
  • How would I call this configuration object from the code to retrieve parameters?
    • Should this object be strongly-typed?
  • I will need access to this structure from a lot of different places in the code. What is the most elegant way to retrieve the values in the object without passing the object itself around everywhere?

I have a feeling that it should be a single, strongly-typed object and that it should be an instantiated object that is retrieved from a repository with a static retrieval method however I really want validation of this method.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
149 views
Welcome To Ask or Share your Answers For Others

1 Answer

I would use a single configuration object like the following:

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

Since this is a singleton, it will create one and only one instance of itself the first time a public static property is referenced from the Setting object.

When the object is created, it reads from the Settings.ini file. The settings file is a plain-text file with a simple key : value structure that might look like this:

FrameMax : 12
VideoDir : C:VideosBest

The object uses reflection to discover each property and to store its initial value. In this example, two properties have been defined:

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

The code as written handles Int32 and String types. By adding additional case statements to the switch statement, you could easily add support for types like Float and Decimal.

To change a setting, you would use something like:

Setting.FrameMax = 5;

To retrieve a setting, you would use something like:

if (Setting.FrameMax > 10) ...

You'll notice that all the properties are strongly-typed. Also, you don't have to pass the Setting object around, as all the Setting properties are static and always available everywhere.

I hope this idea is helpful.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...