TJMatheson
TJMatheson

Reputation: 71

Transform a dictionary into an object model

I have a dictionary (like) object, with Field Name, and field value. I have a defined model already for many different entities. One of which I have included below. However, I cannot explicitly code for this one model, I want to create common code, the convert the entity model to the person model, or any other type of model. The idea, is that it could be any of the models, however I would know which at the point of execution.

In order to reduce code, I want to map these, based on the values in the dictionary, rather than, explicitly identify each field. The destination involves 100's of models, so you can see how it will greatly reduce code, and effort. I want to be able to build the model object, from just this definition, rather than mapping each field.

source

public class EntityModel
{
     public string fieldname { get; set;}
     public string fieldvalue { get; set;}
}

public class ListEntityModel
{
     public list<EntityModel> list {get;set;}

     public string GetValue ( string fname )
     {
           foreach(var em in list )
           {
                 if (em.fieldname == fname) return em.fieldvalue;
           }
           return "";
     }
}

destination

public class PersonModel {
     public string id { get;set; }
     public string name { get;set;}
     public string manyotherfields { get;set; }
}

roughly how it would work

public PersonModel Transformer(ListEntityModel lem) {
    

}

the boring way

public PersonModel TransformMeToModel(ListEntityModel lem) {
   var model =  new PersonModel
   {
       id = lem.GetValue("id"),
       name = lem.GetValue("name"),
       manyotherfields = lem.GetValue("manyotherfields")
   };
   return model;
}


Upvotes: 2

Views: 1309

Answers (2)

GSerg
GSerg

Reputation: 78134

public class PersonModel
{
    public string id { get; set; }
    public string name { get; set; }
    public string manyotherfields { get; set; }
}
public static T TransformMeToModel<T>(Dictionary<string, string> lem) where T : new()
{
    T t = new T();

    foreach (var p in typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public))
    {
        if (lem.TryGetValue(p.Name, out string v))
        {
            p.SetValue(t, v);
        }
    }

    return t;
}
var props = new Dictionary<string, string> { { "id", "1" },  {"name", "one" }, { "manyotherfields", "m" } };

var instance = TransformMeToModel<PersonModel>(props);

Upvotes: 2

SomeBody
SomeBody

Reputation: 8743

You can use reflection:

public T TransformMeToModel<T>(ListEntityModel lem)
    {
        var model = Activator.CreateInstance(typeof(T));
        foreach(var entry in lem.list)
        {
            model.GetType().GetProperty(entry.fieldname).SetValue(model, entry.fieldvalue);
        }
        return (T)model;
    }

But be aware that an exception is thrown when when your ListEntityModeldoes not match to the properties (either name or type) of your target type. Also, your target class needs a default constructor.

Online demo: https://dotnetfiddle.net/fHBJlh

Upvotes: 2

Related Questions