这是第一次,我用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. jQuery.each列表和非列表
- 3. 列表和子列表
- 4. 列表和链接列表
- 5. SQL列表和只列表
- 6. 列表和阵列
- 7. 列表和Parallel.Invoke
- 8. XmlSerialization和列表
- 9. 类和列表
- 10. Haskell:runGetState和列表
- 11. 列和表 - SQLite
- 12. 报表1列和多列
- 13. 列表<Object>和列表<?>
- 14. 数组列表和列表视图
- 15. 管理列表和子列表与MySQL
- 16. 列表除了和union两个列表
- 17. 函数列表和解压列表
- 18. Python列表和NumPy列表输出
- 19. 处理列表和列表框项目
- 20. 列表索引Python和列表理解
- 21. Python - 使用列表()和操作列表
- 22. 响应式列表和列表项目
- 23. 创建列表和选择列表值
- 24. 列表和索引函数列表[Python]
- 25. 列表的列表CSS和HTML里面
- 26. POI和Excel列表或表
- 27. Python OOP和列表
- 28. 谓词和列表
- 29. 迭代和列表
- 30. 列表和集合