I have several entities that I'd like to transform. Here is an example:
public class FromClass
{
public string Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public string TimeStamp { get; set; }
}
public class ToClass
{
public int Id { get; set; }
public string Name { get; set; }
public int TypeId { get; set; }
public DateTime TimeStamp { get; set; }
}
I've made a class of how the transformation should be done for each property like this:
public interface ITransformationRule
{
T Transform<T>(string value);
}
public class ColumnDescription
{
public string SourceColumnName { get; set; }
public string TargetObjectProperty { get; set; }
public ITransformationRule TransformationRule { get; set; }
}
The source properties are always strings and the data is validated in a previous step so I know I can cast without exceptions. So for each property I have a transformationrules. Some transformations are plain casts while other do lookup in tables.
In the above example I'd have a List of ColumnDescriptions like this:
public List<ColumnDescription> TransformationDescription = new List<ColumnDescription>
{
new ColumnDescription{SourceColumnName = "Id", TargetObjectProperty = "Id", TransformationRule = new IntegerTransformation() }
};
etc... Now here is where I'm lost (or perhaps the ITransformationRule interface should look a little bit different). I've written the IntegerTransformationClass like this:
public class IntegerTransformation : ITransformationRule
{
public T Transform<T>(string value)
{
object returnvalue = int.Parse(value);
return (T) returnvalue;
}
}
finally I'm looping through the properties in the list like this:
foreach (var row in TransformationDescription)
{
ยจ...
var classType = row.TransformationRule.GetType();
var methodInfo = classType.GetMethod("Transform");
var generic = methodInfo.MakeGenericMethod(toProp.GetType());
var parameters = new object[] { toProp.ToString() };
var toValue = generic.Invoke(specialTransform.TransformationRule, parameters);
toProp.SetValue(toObj, Convert.ChangeType(toValue, toProp.PropertyType), null);
}
At runtime a get the exeption.Unable to cast object of type 'System.Int32' to type 'System.Reflection.RuntimePropertyInfo' when returning from the TransformationClass.
Perhaps I'm going about the problem in a totaly wrong way. Any input would be appreciated.
This line is the problem:
var generic = methodInfo.MakeGenericMethod(toProp.GetType());
You're calling GetType()
on toProp
- that will return some type derived from PropertyInfo
. You actually want the property type, so just change it to:
var generic = methodInfo.MakeGenericMethod(toProp.PropertyType);
See more on this question at Stackoverflow