這是第一次,我用EmitMapper。 我有對象前的列表:客戶,我想我怎麼能做到這一點映射此列表中的IEnumerable CustomerDTO的? TNXEmitMapper和列表
2
A
回答
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());
這救了我的一天,我希望能救你呢!呵呵呵
相關問題
- 1. emitmapper循環引用
- 2. 帶有對象源類型的EmitMapper
- 3. Python列表和新列表
- 4. 列表和鏈接列表
- 5. SQL列表和只列表
- 6. 列表和子列表
- 7. 散列表和散列表
- 8. 列表和對象列表
- 9. jQuery.each列表和非列表
- 10. 列表和陣列
- 11. 遍歷列表的列表和列表的列表
- 12. 列表和Parallel.Invoke
- 13. 類和列表
- 14. XmlSerialization和列表
- 15. Datareader和列表
- 16. 列表和
- 17. 列和表 - SQLite
- 18. Haskell:runGetState和列表
- 19. 報表1列和多列
- 20. 匹配列和列表
- 21. Python列表 - 行和列
- 22. C#中列表的列表和值#
- 23. Python列表和本地列表聲明
- 24. 面板和列表組下拉列表
- 25. Python列表和NumPy列表輸出
- 26. 管理列表和子列表與MySQL
- 27. 響應式列表和列表項目
- 28. CheckedListBox和對象列表的列表
- 29. 多個列表或列表和getSublist()(Java)
- 30. 數組列表和列表視圖