如何教导Automapper将X映射到IContainer< Y> ;? [英] How do I teach Automapper to map X to IContainer<Y>?
问题描述
这是从模型到mvvmcross视图模型的映射,在这里您可以使用一些容器类,例如:
This came up mapping from models to mvvmcross viewmodels, where you have some container classes you might use, for example:
namespace MvvmCross.Binding
{
interface INC<T>
{
T Value { get; set; }
}
}
class model
{
String name { get; set; }
DateTime when { get; set; }
othermodel data { get; set; }
}
class viewmodel
{
INC<String> Name { get; set; }
INC<String> When { get; set; }
INC<otherviewmodel> Data { get; set; }
}
-
我需要教AutoMapper在不指定A或B的情况下从
A
映射到INC<B>
(并反向).I need to teach AutoMapper to map from
A
toINC<B>
(and back), without specifiying A or B.应该创建空目标
INC<>
,不应该重新创建非null.Null destination
INC<>
should be created, non-null should not be re-created.映射应继续以使
destination.Value = Mapper.Map<A,B>(source)
.映射
null --> INC<T>
应该导致INC<T>.Value = SomeDefaultValue
推荐答案
使用
ForAllMaps
,您可以获取源/目标类型并提供封闭的,完全通用的转换器类型.如果您想直接调用-Map<X,IContainer<Y>
,但这没有帮助,但是您不需要.By using
ForAllMaps
, you can get the source/destination types and provide a closed, fully generic converter type. This doesn't help if you want to directly call -Map<X,IContainer<Y>
, but you shouldn't need to.Mapper.Initialize(c => { c.CreateMap<model, viewmodel>().ReverseMap(); c.ForAllMaps((p, mc) => { Type st = p.SourceType, sct = GetContained(st); Type dt = p.DestinationType, dct = GetContained(dt); if (sct != null) mc.ConvertUsing(typeof(TCReverse<,>).MakeGenericType(sct, dt)); if (dct != null) mc.ConvertUsing(typeof(TCForward<,>).MakeGenericType(st, dct)); }); }); Mapper.AssertConfigurationIsValid(); Mapper.Map<viewmodel>(new model()); Mapper.Map<model>(new viewmodel());
使用简单的转换器:
public class TCReverse<X,Y> : ITypeConverter<IContainer<X>, Y> { public Y Convert(IContainer<X> source, Y destination, ResolutionContext context) { var use = source == null ? default(X) : source.Value; return context.Mapper.Map(use, destination); } } public class TCForward<X,Y> : ITypeConverter<X, IContainer<Y>> { public IContainer<Y> Convert(X source, IContainer<Y> destination, ResolutionContext context) { if (destination == null) destination = new Container<Y>(); destination.Value = context.Mapper.Map(source, destination.Value); return destination; } }
我在这里使用了辅助方法:
And I used a helper method here:
Type GetContained(Type t) { return t.GetInterfaces() .Concat(new[] { t }) .Where(x => x.IsGenericType) .Where(x => typeof(IContainer<>).IsAssignableFrom(x.GetGenericTypeDefinition())) .Select(x => x.GenericTypeArguments[0]) .FirstOrDefault(); }
这篇关于如何教导Automapper将X映射到IContainer< Y> ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!