如何教导Automapper将X映射到IContainer< Y&gt ;? [英] How do I teach Automapper to map X to IContainer<Y>?

查看:117
本文介绍了如何教导Automapper将X映射到IContainer< Y&gt ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是从模型到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 to INC<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&lt; Y&gt ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆