问题描述:

I'm trying to maintain a dictionary of configurations.

Here is my abstract class.

[Serializable]

public abstract class Configuration

{

}

And here is a concrete class (for the moment, I just have only this class).

[Serializable]

public class BinaryProblemConfiguration : Configuration

{

[XmlAttribute]

public decimal MinValue { get; set; }

[XmlAttribute]

public decimal MaxValue { get; set; }

}

I've got a class which contains a Dictionary of configuration levels.

  • The first parameter is the name of the configuration. When name="" means default configuration.
  • Level means the difficulty. There are three levels: Easy, Medium and Hard.
  • And the third one is the configuration.

/// <summary>

/// The abstract level configuration allows descendent classes to configure themselves

/// </summary>

public abstract class LevelConfiguration

{

private Dictionary<string, Dictionary<Levels, Configuration>> _configurableLevels = new Dictionary<string, Dictionary<Levels, Configuration>>();

/// <summary>

/// Adds a configurable level.

/// </summary>

/// <param name="level">The level to add.</param>

/// <param name="problemConfiguration">The problem configuration.</param>

protected void AddConfigurableLevel(string name, Levels level, Configuration problemConfiguration)

{

if (!_configurableLevels.ContainsKey(name))

{

_configurableLevels.Add(name, new Dictionary<Levels, Configuration>());

}

_configurableLevels[name].Add(level, problemConfiguration);

}

/// <summary>

/// Returns all the configurable levels.

/// </summary>

/// <param name="level"></param>

protected void RemoveConfigurableLevel(string name, Levels level)

{

_configurableLevels[name].Remove(level);

}

/// <summary>

/// Returns all the configurable names.

/// </summary>

/// <returns></returns>

public IEnumerable<string> GetConfigurationNames()

{

return _configurableLevels.Keys;

}

/// <summary>

/// Returns all the configurable levels.

/// </summary>

/// <returns></returns>

public IEnumerable<Levels> GetConfigurationLevels(string name)

{

return _configurableLevels[name].Keys;

}

/// <summary>

/// Gets the problem configuration for the specified level

/// </summary>

/// <param name="level">The level.</param>

/// <returns></returns>

public Configuration GetProblemConfiguration(string name, Levels level)

{

return _configurableLevels[name][level];

}

}

This is the class which create some configurations. I'm creating three default configs and two customs.

public class AdditionLevelConfiguration : LevelConfiguration

{

public AdditionLevelConfiguration()

{

AddConfigurableLevel("", Levels.Easy, GetEasyLevelConfiguration());

AddConfigurableLevel("", Levels.Medium, GetMediumLevelConfiguration());

AddConfigurableLevel("", Levels.Hard, GetHardLevelConfiguration());

AddConfigurableLevel("config2", Levels.Easy, GetEasyLevelConfiguration());

AddConfigurableLevel("config2", Levels.Medium, GetMediumLevelConfiguration());

var configs = this.GetProblemConfiguration("config2", Levels.Medium);

var configs2 = this.GetProblemConfiguration("", Levels.Easy);

}

protected Configuration GetHardLevelConfiguration()

{

return new BinaryProblemConfiguration

{

MinValue = 100,

MaxValue = 1000,

};

}

protected Configuration GetMediumLevelConfiguration()

{

return new BinaryProblemConfiguration

{

MinValue = 10,

MaxValue = 100,

};

}

protected Configuration GetEasyLevelConfiguration()

{

return new BinaryProblemConfiguration

{

MinValue = 1,

MaxValue = 10,

};

}

}

I plan to write these configurations in a XML file. I was thinking of serialize them, but it throws me an error. What should I do?

网友答案:

Another option you may consider is using a DataContractSerializer. I was able to serialize your dictionary of dictionaries this way.

Things to keep in mind if you go this route:

  • You would have to add different attributes. Specifically, you need DataContract on the type and DataMember on the properties.
  • You need to ensure all properties have setters, even if the setters ultimately are private.
  • When creating your DataContractSerializer, you need to ensure it is aware of all your types. Giving it the type of your dictionary takes care of string, Levels, and Configuration, but not BinaryProblemConfiguration. Additional type info can be provided via additional constructor overloads.

Example:

var  dict = new Dictionary<string,Dictionary<Levels,Configuration>> ();
var  wtr = XmlWriter.Create (Console.Out);
var  dcSerializer = new DataContractSerializer (dict.GetType (), new [] {typeof (BinaryProblemConfiguration)});
dcSerializer.WriteObject (wtr, dict);

If you do the above, you could also switch to DataContractJsonSerializer later for a more compact JSON format if you prefer (assuming XML is not a hard requirement, of course).

网友答案:

From what i know classes that implement IDictionary cannot be Xml serialized. Try this http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx, it worked for me.

相关阅读:
Top