mattinsalto
mattinsalto

Reputation: 2366

map entity to runtime created dto

Is there an automagic (automapper?) way to map an entity to a runtime created dynamic object with properties passed as parameters? I want to do an API where the clients can select the properties of the entities they want to fetch. I mean:

class Patient
{
    public int PatientId{ get; set; }
    public string Name{ get; set; }
    public string LastName{ get; set; }
    public string Address{ get; set; }
...
}

getPatient(string[] properties)
{
    //Return an object that has the properties passed as parameters

}

Imagine you only want to fetch a PatientDTO with PatientId and Name:

getPatient(new string[]{"PatientId", "Name"} 

should return

{
    "PatientId": "1234",
    "Name": "Martin",
}

and so on.

For now I'm doing it with Dictionary, but probably there is a better way. This is my approach: For a single object:

public static Dictionary<string, object> getDTO(string[] properties, T entity)
{
     var dto = new Dictionary<string, object>();

      foreach (string s in properties)
      {
        dto.Add(s, typeof(T).GetProperty(s).GetValue(entity));
      }

      return dto;
}

For a list of objects:

public static List<Dictionary<string, object>> getDTOList(string[] properties, List<T> TList)
{
  var dtoList = new List<Dictionary<string, object>>();

  foreach(T entity in TList)
  {
    dtoList.Add(getDTO(properties, entity));
  }

  return dtoList;
}

Thank you.

Upvotes: 0

Views: 1940

Answers (1)

Tim Lentine
Tim Lentine

Reputation: 7862

How about creating a new dynamic object based solely on the specified property fields and returning the dynamic? You will need to add using statements for: System.Dynamic and System.ComponentModel for the following to work.

public static dynamic getDTO(object entity, string[] properties)
{
    IDictionary<string, object> expando = new ExpandoObject();

    foreach (var p in properties)
    {
        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(entity.GetType()))
        {
            if (property.Name == p)
            {
                expando.Add(p, property.GetValue(entity));
                break;
            }
        }
    }
    return expando as ExpandoObject;
}

Calling this method would look something like this:

var patient = new Patient() { PatientId = 1, Name = "Joe", LastName = "Smith", Address = "123 Some Street\nIn Some Town, FL 32333" };
var propList = new string[] { "PatientId", "Name", "Address" };

dynamic result = getDTO(patient, propList);

Console.WriteLine("Id:{0} Name: {1}\nAddress: {2}", result.PatientId, result.Name, result.Address);
Console.ReadLine();

Upvotes: 1

Related Questions