2012-03-05 76 views
2

这是第一次,我用EmitMapper。 我有对象前的列表:客户,我想我怎么能做到这一点映射此列表中的IEnumerable CustomerDTO的? TNXEmitMapper和列表

回答

2

它的简单,如果你有一个列表,并希望将其转换为DTO的列表:

var mapper = ObjectMapperManager.DefaultInstance.GetMapper<Customer, CustomerDTO>(); 

IEnumerable<CustomerDTO> dtos = listOfCustomer.Select(mapper.map); 

的preblem是当列表是在另一个对象,例如用户和UserDTO:

class User { 
    public List<Customer> Customers { get; set; } 
} 

class UserDTO { 
    public IEnumerable<CustomerDTO> Customers { get; set; } 
} 

看来,EmitMapper不支持从列表转换为可枚举。一种支持这将是:

 var customerMapper = ObjectMapperManager 
      .DefaultInstance.GetMapper<Customer, CustomerDTO>(); 
     var mapper = ObjectMapperManager.DefaultInstance 
      .GetMapper<User, UserDTO>(
       new DefaultMapConfig() 
       .ConvertUsing<List<Customer>, IEnumerable<CustomerDTO>>(
        a => a.Select(customerMapper.Map)) 
     ); 
0

这可以创建一个自定义类,实现了接口“ICustomConverterProvider”并增加了ConvertGeneric的“DefaultMapConfig”。

看好EmitMapper的源代码,我发现了一个名为“ArraysConverterProvider”类,这是从ICollections默认的通用转换器阵列。

适应从这个类的代码的IEnumerable集合的工作:

class GenericIEnumerableConverterProvider : ICustomConverterProvider 
    { 
     public CustomConverterDescriptor GetCustomConverterDescr(
      Type from, 
      Type to, 
      MapConfigBaseImpl mappingConfig) 
     { 
      var tFromTypeArgs = DefaultCustomConverterProvider.GetGenericArguments(from); 
      var tToTypeArgs = DefaultCustomConverterProvider.GetGenericArguments(to); 
      if (tFromTypeArgs == null || tToTypeArgs == null || tFromTypeArgs.Length != 1 || tToTypeArgs.Length != 1) 
      { 
       return null; 
      } 
      var tFrom = tFromTypeArgs[0]; 
      var tTo = tToTypeArgs[0]; 
      if (tFrom == tTo && (tFrom.IsValueType || mappingConfig.GetRootMappingOperation(tFrom, tTo).ShallowCopy)) 
      { 
       return new CustomConverterDescriptor 
       { 
        ConversionMethodName = "Convert", 
        ConverterImplementation = typeof(GenericIEnumerableConverter_OneTypes<>), 
        ConverterClassTypeArguments = new[] { tFrom } 
       }; 
      } 

      return new CustomConverterDescriptor 
      { 
       ConversionMethodName = "Convert", 
       ConverterImplementation = typeof(GenericIEnumerableConverter_DifferentTypes<,>), 
       ConverterClassTypeArguments = new[] { tFrom, tTo } 
      }; 
     } 
    } 


class GenericIEnumerableConverter_DifferentTypes<TFrom, TTo> : ICustomConverter 
    { 
     private Func<TFrom, TTo> _converter; 
     public IEnumerable<TTo> Convert(IEnumerable<TFrom> from, object state) 
     { 
      if (from == null) 
      { 
       return null; 
      } 

      TTo[] result = new TTo[from.Count()]; 
      int idx = 0; 
      foreach (var f in from) 
      { 
       result[idx++] = _converter(f); 
      } 

      return result; 
     } 

     public void Initialize(Type from, Type to, MapConfigBaseImpl mappingConfig) 
     { 
      var staticConverters = mappingConfig.GetStaticConvertersManager() ?? StaticConvertersManager.DefaultInstance; 

      var staticConverterMethod = staticConverters.GetStaticConverter(typeof(TFrom), typeof(TTo)); 

      if (staticConverterMethod != null) 
      { 
       _converter = (Func<TFrom, TTo>)Delegate.CreateDelegate(
        typeof(Func<TFrom, TTo>), 
        null, 
        staticConverterMethod 
       ); 
      } 
      else 
      { 
       _subMapper = ObjectMapperManager.DefaultInstance.GetMapperImpl(typeof(TFrom), typeof(TTo), mappingConfig); 

       _converter = ConverterBySubmapper; 
      } 
     } 

     ObjectsMapperBaseImpl _subMapper; 

     private TTo ConverterBySubmapper(TFrom from) 
     { 
      return (TTo)_subMapper.Map(from); 
     } 
    } 


class GenericIEnumerableConverter_OneTypes<T> 
    { 

     public IEnumerable<T> Convert(IEnumerable<T> from, object state) 
     { 
      if (from == null) 
      { 
       return null; 
      } 

      return from; 
     } 
    } 

这段代码仅仅是一个最低限度适应尽可能复制和可applyed到对象与层次的许多层面。

您可以使用上面的代码用下面的命令:

new DefaultMapConfig().ConvertGeneric(
typeof(IEnumerable<>), 
typeof(IEnumerable<>), 
new GenericIEnumerableConverterProvider()); 

这救了我的一天,我希望能救你呢!呵呵呵