How is the namevaluecollection machine for a strongly typed class?

I have my application configuration data stored in a table as shown below:

SettingName SettingValue -------------------- --------------------- PostsPerPage 10 EmailErrors True AdminEmailAddress admin@admin.com 

My dataaccess class returns a namevaluecollection / keyvalue command for parameters stored in a table.

What would be the best way to map namevaluecollection / keyvaluepair to a strongly typed class like the one below, which has properties with a name just like in the SettingName column.

 public class Settings { public int PostsPerPage{get;set;} public bool EmailErrors{get;set;} public string AdminEmailAddress{get;set;} } 
+7
c #
source share
5 answers

Use reflection. In pseudo code:

 Settings mySettingsClass = new Settings(); foreach (KeyValuePair<string, object> kvp in mySettings) { PropertyInfo pi = mySettingsClass.GetType().GetProperty(kvp.key, BindingFlags.Public | BindingFlags.Instance); if (pi != null) { pi.SetValue(mySettingsClass, kvp.Value, null); } } 

Of course, if you read it back from the dataReader, you can use a slightly different approach and avoid using reflection (since the structure of the DataReader and the structure of the target object are known). Using reflection in this case is slower, but it is a good way to display data from one element to another in general - basically you take the source property, see if the target property exists on the target, and then assigns a value, if any.

+3
source share

Adding this answer (the message is outdated, I know) - I had to work out the @slugster answer - it was the most promising.

 NameValueCollection nvc = HttpContext.Current.Request.Form; Settings mySettingsClass = new Settings(); foreach (string kvp in nvc.AllKeys) { PropertyInfo pi = model.GetType().GetProperty(kvp, BindingFlags.Public | BindingFlags.Instance); if (pi != null) { pi.SetValue(model, nvc[kvp], null); } } 

Basically the only difference: @slugster used KeyValuePair , not a NameValueCollection

+3
source share

Use code generation to generate your settings class. I did it and it worked out very well. This is the approach I took:

  • Define your settings in an XML file of your own design. It must determine the minimum names and types of settings. But you can add other things if you want: help lines, default values, check predicates, etc.
  • Use t4 to read in the XML file and create a settings class. (t4 is a code generator built into Visual Studio.)

Code generation is often useful in cases where you are faced with the limitations of static type checking. The good thing about code generation is that the code is statically typed, so you get a compile-time type check, which of course is one of the benefits of static input.

+1
source share

Here is another shortcut, if your project has a Newtonsoft Json library - you can use it as a translation mechanism. Not sure if all this is great, but very concise and simple ...

Suppose a "form" is your "NameValueCollection" object ...

 // convert to a string/string dictionary and remove anynulls that may have been passed in as a string "null" var formDictionary = form.AllKeys .Where(p => form[p] != "null") .ToDictionary(p => p, p => form[p]); string json = JsonConvert.SerializeObject(formDictionary); var myObject = JsonConvert.DeserializeObject<MyClass>(json); 
+1
source share

Using the System.Reflection Namespace:

http://www.dotnetspider.com/resources/19232-Set-Property-value-dynamically-using-Reflection.aspx

You get the type using GetType () of the object or execute it dynamically, use GetProperties to get all the properties from the type or GetProperty to get one property, and call SetValue with the value from the dictionary.

This is the easiest way. There may be some kind of mapper object that can do this too.

NTN.

0
source share

All Articles