J'ai un dictionnaire contenant des valeurs de configuration pour d'autres classes (tâches qui seront exécutées périodiquement en effectuant une logique spécialisée) qui sont conservées dans une base de données puis renvoyées au moment de l'exécution.Meilleure façon de créer un wrapper fortement typé pour Dictionary <string, string>
Je souhaite créer un wrapper fortement typé pour ce dictionnaire, à la fois pour permettre un accès facile aux valeurs et pour les convertir au bon type.
Au moment où je quelque chose comme ceci:
public class ConfigurationWrapper {
Dictionary<string, string> _configuration;
public ConfigurationWrapper(Dictionary<string, string> configuration) {
_configuration = configuration;
InitializeDefaultValues();
}
public virtual GetConfigurationCopy() {
return new Dictionary(_configuration);
}
protected InitializeDefaultValues() {
Type t = GetType();
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(t);
foreach (PropertyDescriptor property in properties) {
AttributeCollection attributes = property.Attributes;
DefaultValueAttribute defaultValue = (DefaultValueAttribute)attributes[typeof(DefaultValueAttribute)];
if (defaultValue != null) {
if (!Configuration.ContainsKey(property.Name)) {
Configuration[property.Name] = Convert.ToString(defaultValue.Value, CultureInfo.InvariantCulture);
}
}
}
}
}
public class MyTaskConfigurationWrapper : ConfigurationWrapper {
private const string MyIntPropertyKey = "MyIntProperty";
[DefaultValue(7)]
int MyIntProperty {
get { return Convert.ToInt32(_configuration[MyIntPropertyKey], CultureInfo.InvarientCulture); }
set { _configuration[MyIntPropertyKey] = value.ToString(CultureInfo.InvarientCulture); }
}
// More properties of various types.
}
Ma question est de savoir s'il y a un moyen d'améliorer cette conception. Une chose que j'ai considéré utilise la réflexion pour obtenir le nom de la propriété (et donc la valeur de configuration) comme discuté here. Cela évite d'avoir à créer une clé de chaîne et oblige implicitement la clé à avoir le même nom que la propriété (ce qui est requis pour que le code InitializeDefaultValues()
fonctionne), mais cela obscurcit aussi le fait que c'est le cas et que le nom de la valeur de configuration changera si le nom de la propriété est modifié. C'est donc un compromis.
Cela ressemblerait à quelque chose comme ce qui suit:
// Could alternately use PropertyHelper example with some compile time checking
protected string GetProperty(MethodBase getMethod) {
if (!getMethod.Name.StartsWith("get_") {
throw new ArgumentException(
"GetProperty must be called from a property");
}
return _configuration[getMethod.Name.Substring(4)];
}
protected string SetProperty(MethodBase getMethod, string value) {
// Similar to above except set instead of get
}
[DefaultValue(7)]
int MyIntProperty {
get { return Convert.ToInt32(GetProperty(MethodInfo.GetCurrentMethod(), CultureInfo.InvarientCulture); }
set { SetProperty(MethodInfo.GetCurrentMethod(), value.ToString(CultureInfo.InvarientCulture); }
}
Je n'avais pas rencontré Convert.ChangeType() auparavant. Merci de l'avoir signalé. Ce sera très utile. Le reste de la suggestion est utile aussi. –