asp.net-mvc-2 - tutorial - poco vs dto
De AutoMapper a Emit Mapper (1)
Para Record, esta es la mejor solución que encontré sobre cómo hacerlo:
http://emitmapper.codeplex.com/discussions/259655
Verifica la solución en la última publicación. Funciona realmente bien.
Actualización: el código para referencia futura:
public class ExtDefaultMapConfig<TSrc, TDst> : DefaultMapConfig
{
private readonly Dictionary<string, Func<TSrc, object>> _properties = new Dictionary<string, Func<TSrc, object>>();
public ExtDefaultMapConfig<TSrc, TDst> ForMember(string property, Func<TSrc, object> func)
{
if (!_properties.ContainsKey(property))
_properties.Add(property, func);
return this;
}
public ExtDefaultMapConfig<TSrc, TDst> ForMember(Expression<Func<TDst, object>> dstMember, Func<TSrc, object> func)
{
var prop = ReflectionHelper.FindProperty(dstMember);
return ForMember(prop.Name, func);
}
public ExtDefaultMapConfig<TSrc, TDst> Ignore(Expression<Func<TDst, object>> dstMember)
{
var prop = ReflectionHelper.FindProperty(dstMember);
IgnoreMembers<TSrc, TDst>(new[] { prop.Name });
return this;
}
public override IMappingOperation[] GetMappingOperations(Type from, Type to)
{
var list = new List<IMappingOperation>();
list.AddRange(base.GetMappingOperations(from, to));
list.AddRange(
FilterOperations(
from,
to,
ReflectionUtils.GetPublicFieldsAndProperties(to)
.Where(f => _properties.ContainsKey(f.Name))
.Select(
m =>
(IMappingOperation)new DestWriteOperation
{
Destination = new MemberDescriptor(m),
Getter =
(ValueGetter<object>)
(
(value, state) =>
{
Debug.WriteLine(string.Format("Mapper: getting value of field or property {0}", m.Name));
return ValueToWrite<object>.ReturnValue(_properties[m.Name]((TSrc) value));
}
)
}
)
)
);
return list.ToArray();
}
}
class ReflectionHelper
{
public static MemberInfo FindProperty(LambdaExpression lambdaExpression)
{
Expression expression = lambdaExpression;
bool flag = false;
while (!flag)
{
switch (expression.NodeType)
{
case ExpressionType.Convert:
expression = ((UnaryExpression)expression).Operand;
break;
case ExpressionType.Lambda:
expression = ((LambdaExpression)expression).Body;
break;
case ExpressionType.MemberAccess:
MemberExpression memberExpression = (MemberExpression)expression;
if (memberExpression.Expression.NodeType != ExpressionType.Parameter && memberExpression.Expression.NodeType != ExpressionType.Convert)
throw new ArgumentException(string.Format("Expression ''{0}'' must resolve to top-level member.", lambdaExpression), "lambdaExpression");
return memberExpression.Member;
default:
flag = true;
break;
}
}
return null;
}
public static object GetValue(string property, object obj)
{
PropertyInfo pi = obj.GetType().GetProperty(property);
return pi.GetValue(obj, null);
}
}
Recientemente descubrí AutoMapper para enlazar ViewModels y mis objetos DB reales. Lo uso en la forma descrita aquí: http://automapper.codeplex.com/wikipage?title=Projection&referringTitle=Home
Descubrí Emit Mapper en :), pero no encuentro ninguna similar (donde puedo especificar reglas de proyección personalizadas):
.ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date))
¡Gracias por adelantado!