jeudi 17 mai 2018

C#: Pass reflection type into class constructor

I've got a generic method that takes an arbitrary JObject (from JSON.net) and converts it into the generically typed object.

So, let's simplify my conversion method to look like the following:

private async Task<T> ConvertToObject(JObject obj) {
    //Lots of other stuff yielding in the creation of newObj
    var result = newObj.ToObject<T>();
    return result;
}

Now this method works fine as-is, but I want to modify the method so I can properly do the same for complex properties within the generic object that aren't available in my JObject (e.g. I have to look them up separately, do this same conversion and apply to this object result).

My approach so far is to loop through all the properties, identify the complex types, perform the lookup to retrieve their values from my data store, then execute the above against them (potentially recursively if they too have any complex objects), then write that value back out to this complex property, repeat for any others and then as before, return that result.

I'm retrieving the properties via Reflection:

var properties = result.GetType().GetProperties();
foreach (var property in properties) {
  if (IsSimple(property.PropertyType)
    continue;

  //Do external lookup

  var convertedValue = new ConversionTool<>().Lookup(query);
}

Now, that last line is where I'm having my problem. I'm expected to pass a class name into this, not just a type, but I only know the type at runtime per the reflection methods above. I found a post at http://www.paulbatum.com/2008/08/less-fragile-way-to-invoke-generic.html detailing how to make this work if I were simply passing the generic type into a method and he explains the issue with using Activator.CreateInstance in the comments, but it seems like I know the type I'd want to put there - I just don't know it until it runs (and I retrieve it via reflection).

This seems like an issue that ORMs would run into when it comes to populating complex properties of their entities, but I'm having a difficult time finding how they're doing this.

Given that the caller of this method is aware at runtime what the intended type is, how might I go about passing that type into the generic class constructor so I might call it recursively for each complex member of a given type?





Aucun commentaire:

Enregistrer un commentaire