I was wondering if I could find out the difference in performance from others experience with reflection and DTO objects inside a WCF service. I have the code below that I was using to create a DTO object from an Entity object using Linq.
using (dashEntities context = new dashEntities())
{
result = context.GetAlerts().Select(m => new AlertItemDTO()
{
}).ToList();
Another programmer when building their WCF Service wrote a Generic method using Reflection to do the same conversion:
private object TransferEntityToDTO(object dto, object entity)
{
Type entityType = entity.GetType();
// Use reflection to get all properties
foreach (PropertyInfo propertyInfo in entityType.GetProperties())
{
if (propertyInfo.CanRead)
{
List<PropertyInfo> dtoProperties = dto.GetType().GetProperties().ToList();
foreach (PropertyInfo dtoProperty in dtoProperties)
{
if (dtoProperty.Name == propertyInfo.Name)
{
object value = propertyInfo.GetValue(entity, null);
if (value != null && value.ToString() != "" && value.ToString() != "1/1/0001 12:00:00 AM")
{
// This section gets the type of of the property and casts
// to it during runtime then sets it to the corresponding
// dto value:
// Get current class type
Type currentClassType = this.GetType();
//Get type of property in entity object
Type propertyType = Type.GetType(propertyInfo.PropertyType.FullName);
// Get the Cast<T> method and define the type
MethodInfo castMethod = currentClassType.GetMethod("Cast").MakeGenericMethod(propertyType);
// Invoke the method giving value its true type
object castedObject = castMethod.Invoke(null, new object[] { value });
dtoProperty.SetValue(dto, value, null);
}
break;
}
}
}
}
return dto;
}
/// <summary>
/// Used in TransferEntityToDTO to dynamically cast objects to
/// their correct types.
/// </summary>
/// <typeparam name="T">Type to cast object to</typeparam>
/// <param name="o">Object to be casted</param>
/// <returns>Object casted to correct type</returns>
public static T Cast<T>(object o)
{
return (T)o;
}
Obviously, the second technique is harder to read and more lengthy, but it is more generic and could be used in multiple services.
My Question is, does the ability to make it generic outweigh the performance hit from using reflection and if not, why? I found a lot of confusing articles and answers to what makes reflection expensive. I assume part of it is because it needs to look for the object it needs without already knowing, kind of like using the Generic Exception for everything when you know the exception you will get.
Can someone shed some light on this for me please. Thanks
The main difference between these two solutions is that the first uses a projection and the second maps the original entity. For entities that are only a small subset of the original entity (e.g. dtos for lists) it should always be faster to query only the projected properties instead of the complete entity (perhaps with nested entities and properties you don’t need…), which is then mapped to the dto.
To combine the advantages of both solutions (projection + generic solution) you could automagically create projection expressions, cache them and use them within a Select(Expression<…>) call like in your original solution. So all mappings are only created once, you get your dtos directly and only neccessary columns are queried. Have a look at this article and the comments: Stop using AutoMapper in your Data Access Code.
AutoMapper can also build mapping expressions, but it will only map simple properties (as far as I understood it from the source code). With a custom solution and some ‘expression magic’ you could also support complex mappings that are then translated to sql by entity framework:
This code here on github is a good starting point.