2010-12-07 32 views
4

J'ai récemment découvert AutoMapper pour créer un pont entre ViewModels et mes objets de base de données réels. Je l'utilise de la manière decribed ici: http://automapper.codeplex.com/wikipage?title=Projection&referringTitle=HomeDe AutoMapper à Emitter Mapper

J'ai découvert Emit Mapper à :), mais je ne peux pas trouver anytning similaire à (où je peux spécifier des règles de projection sur mesure):

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

Merci d'avance!

Répondre

2

Pour le dossier c'est la meilleure solution que je suis tombé sur la façon de le faire:

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

Vérifiez la solution sur le dernier message. Cela fonctionne vraiment bien.

Mise à jour: Le code pour référence future:

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

peut-être vous copier le code ici pour référence? – artvolk