[英]How to use Mapper.Map with ConstructUsing and AutoMapper?
[英]How to create generic mapping with AutoMapper and ConstructUsing
我有一個地圖配置:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<IDictionary<int, MyType1>, List<MyType1>>().ConstructUsing(
x0 => x0?.OrderBy(x => x.Key).Select(x => x.Value).ToList());
});
如何更改它以與“所有MyTypes”一起使用?
我想將任何T類型從IDictionary<int, T>
轉換為List<T>
。
我發現一個非常丑陋的解決方案:
cfg.CreateMap(typeof(IDictionary<,>), typeof(List<>)).ConstructUsing(
x0 =>
{
if (x0 == null)
{
return null;
}
var dict = (IEnumerable)x0;
var type = x0.GetType().GetGenericArguments()[1];
var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
CastDictionaryEntry(dict).OrderBy(x => x.Key).ForEach(x => list.Add(x.Value));
return list;
}
);
和:
static IEnumerable<DictionaryEntry> CastDictionaryEntry(IEnumerable dict)
{
foreach (var item in dict)
{
yield return (DictionaryEntry)item;
}
}
有沒有更簡單的方法可以做到這一點?
我認為可以,但是我仍然沒有針對廣泛的輸入進行測試-
class ABC
{
public int MyProperty { get; set; }
public int MyProperty2 { get; set; }
}
static List<T> ConfigureMap<T>(Dictionary<int, T> input) where T : class
{
AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap(input.GetType(), typeof(List<T>))
.ConstructUsing(Construct));
return Mapper.Map<List<T>>(input);
}
private static object Construct(object arg1, ResolutionContext arg2)
{
if (arg1 != null)
{
var val = arg1 as IDictionary;
var argument = val.GetType().GetGenericArguments()[1];
if (val != null)
{
var type = Activator.CreateInstance(typeof(List<>).MakeGenericType(argument));
foreach (var key in val.Keys)
{
((IList)type).Add(val[key]);
}
return type;
}
}
return null;
}
var so = new Dictionary<int, ABC> { { 1, new ABC { MyProperty = 10, MyProperty2 = 30 } } };
var dest = new List<ABC>();
var res = ConfigureMap<ABC>(so);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.