简体   繁体   中英

Dictionary<string,object> to object mapper

Is there any object-object mapper that can map properties from a dictionary (or other name-value collection)?

Let's say I have classes

public class SomeClass
{
    public string Text { get; set; }
    public Address HomeAddress { get; set; }
    public List<int> Numbers { get; set; }
}
public class Address
{
    public string Street { get; set; }
    public string PostalCode { get; set; }
    public string City { get; set; }    
}

What I would like to do is

var values = new Dictionary<string,object>();
values.Add("Text","Foo");
values.Add("HomeAddress.Street","Some street 123");
values.Add("HomeAddress.PostalCode","12345");
values.Add("HomeAddress.City","Some city");
values.Add("Numbers[0]",123);
values.Add("Numbers[1]",234);
values.Add("Numbers[2]",345);

SomeClass some = aMapperTool.CreateFromDictionary<SomeClass>(values);

That's basically like the DefaultModelBinder in ASP.NET MVC, which requires a lot of context and metadata related stuff and therefore isn't quite handy.

You can leverage the ComponentModel functionality (this has been addressed elsewhere in stackoverflow

how to set nullable type via reflection code ( c#)?

using System.ComponentModel;   

public void FillMeUp(Dictionary<string, string> inputValues){

        PropertyInfo[] classProperties  = this.GetType().GetProperties();

       var properties = TypeDescriptor.GetProperties(this);

       foreach (PropertyDescriptor property in properties)
       {
           if (inputValues.ContainsKey(property.Name))
           {
               var value = inputValues[property.Name];
               property.SetValue(this, 
                                 property.Converter.ConvertFromInvariantString(value));
           }
       }

You won't get around reflection or expression trees for this.

With reflection, it would be roughly the following:

  1. create an object of T
  2. iterate over the keys in details , if needed, construct the actual property name out of it ( HomeAddress.Street -> HomeAdress , or Numbers[0] -> Number ). Depending on the type of the property (if you find a . , you need to construct the child object first, if you find a [ , you need to initialize an IEnumerable ).
  3. after constructing any child structures, construct the parent object.

While this is a possible solution, there is one question going through my head: "Why?"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM