From AutoMapper to Emit Mapper

妖精的绣舞 提交于 2019-12-10 17:29:37

问题


I've recently discovered AutoMapper for bridging ViewModels and my actual DB objects. I use it in the way decribed here: http://automapper.codeplex.com/wikipage?title=Projection&referringTitle=Home

I've discovered Emit Mapper to :), but I can't find anytning similar to (where I can specify custom projecting rules):

    .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date))

Thanks in advance!


回答1:


For the Record this is the best solution that I came across on how to do it:

http://emitmapper.codeplex.com/discussions/259655

Check the solution on the last post. It works really well.

Update: The code for future reference:

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);
        }
    }  


来源:https://stackoverflow.com/questions/4382070/from-automapper-to-emit-mapper

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!