2012-03-05 42 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()); 

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