public class SimpleDtoMapper<TIn, TOut>
{
private static Func<TIn, TOut> _mapper;
static SimpleDtoMapper()
{
var typeIn = typeof(TIn);
var typeOut = typeof(TOut);
var parameterExpression = Expression.Parameter(typeIn, "p");
List<MemberBinding> bindings = new List<MemberBinding>();
var typeOutProps = typeOut.GetProperties();
var typeInProps = typeIn.GetProperties();
foreach (var item in typeOutProps)
{
var inProp = typeInProps.FirstOrDefault(i => i.Name == item.Name);
if (inProp != null)
{
bindings.Add(Expression.Bind(item, Expression.Property(parameterExpression, inProp)));
}
}
var typeOutFields = typeOut.GetFields();
var typeInFields = typeIn.GetFields();
foreach (var item in typeOutFields)
{
var inField = typeInFields.FirstOrDefault(i => i.Name == item.Name);
if (inField != null)
{
bindings.Add(Expression.Bind(item, Expression.Field(parameterExpression, inField)));
}
}
Expression<Func<TIn, TOut>> copyExpression = Expression.Lambda<Func<TIn, TOut>>(
Expression.MemberInit(Expression.New(typeOut), bindings.ToArray()),
new ParameterExpression[1] { parameterExpression });
_mapper = copyExpression.Compile();
}
public static TOut Map(TIn x)
{
return _mapper.Invoke(x);
}
}