Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert class to dynamic and add properties

Tags:

c#

I have a class MyClass. I would like to convert this to a dynamic object so I can add a property.

This is what I had hoped for:

dynamic dto = Factory.Create(id);
dto.newProperty = "123";

I get the error:

WEB.Models.MyClass does not contain a definition for 'newProperty'

Is that not possible?

like image 545
Sean Avatar asked Mar 16 '17 14:03

Sean


2 Answers

The following has worked for me in the past:
It allows you to convert any object to an Expando object.

public static dynamic ToDynamic<T>(this T obj)
{
    IDictionary<string, object> expando = new ExpandoObject();

    foreach (var propertyInfo in typeof(T).GetProperties())
    {
        var currentValue = propertyInfo.GetValue(obj);
        expando.Add(propertyInfo.Name, currentValue);
    }
    return expando as ExpandoObject;
}

Based on: http://geekswithblogs.net/Nettuce/archive/2012/06/02/convert-dynamic-to-type-and-convert-type-to-dynamic.aspx

like image 137
StfBln Avatar answered Oct 27 '22 21:10

StfBln


As my object has JSON specific naming, I came up with this as an alternative:

public static dynamic ToDynamic(this object obj)
{
  var json = JsonConvert.SerializeObject(obj);
  return JsonConvert.DeserializeObject(json, typeof(ExpandoObject));
}

For me the results worked great:

Model:

public partial class Settings
{
  [JsonProperty("id")]
  public int Id { get; set; }

  [JsonProperty("runTime")]
  public TimeSpan RunTime { get; set; }

  [JsonProperty("retryInterval")]
  public TimeSpan RetryInterval { get; set; }

  [JsonProperty("retryCutoffTime")]
  public TimeSpan RetryCutoffTime { get; set; }

  [JsonProperty("cjisUrl")]
  public string CjisUrl { get; set; }

  [JsonProperty("cjisUserName")]
  public string CjisUserName { get; set; }

  [JsonIgnore]
  public string CjisPassword { get; set; }

  [JsonProperty("importDirectory")]
  public string ImportDirectory { get; set; }

  [JsonProperty("exportDirectory")]
  public string ExportDirectory { get; set; }

  [JsonProperty("exportFilename")]
  public string ExportFilename { get; set; }

  [JsonProperty("jMShareDirectory")]
  public string JMShareDirectory { get; set; }

  [JsonIgnore]
  public string Database { get; set; }
}

I used it in this manner:

private static dynamic DynamicSettings(Settings settings)
{
  var settingsDyn = settings.ToDynamic();
  if (settingsDyn == null)
    return settings;
  settingsDyn.guid = Guid.NewGuid();
  return settingsDyn;
}

And received this as a result:

{
  "id": 1,
  "runTime": "07:00:00",
  "retryInterval": "00:05:00",
  "retryCutoffTime": "09:00:00",
  "cjisUrl": "xxxxxx",
  "cjisUserName": "xxxxx",
  "importDirectory": "import",
  "exportDirectory": "output",
  "exportFilename": "xxxx.xml",
  "jMShareDirectory": "xxxxxxxx",
  "guid": "210d936e-4b93-43dc-9866-4bbad4abd7e7"
}

I don't know about speed, I mean it is serializing and deserializing, but for my use it has been great. A lot of flexability like hiding properties with JsonIgnore.

Note: xxxxx above is redaction. :)

like image 41
Rob10e Avatar answered Oct 27 '22 22:10

Rob10e