zoukankan      html  css  js  c++  java
  • 09.AutoMapper 之自定义类型转换器(Custom Type Converters)

    https://www.jianshu.com/p/47054d92db2a

    自定义类型转换器(Custom Type Converters)

    有时需要完全控制一种类型到另一种类型的转换。这一般发生在两种类型不同,已经存在转换函数,并且希望从弱类型转变为强类型,如源类型的字符串到目标类型Int32。

    例如,假设我们的源类型为:

    public class Source
    {
        public string Value1 { get; set; }
        public string Value2 { get; set; }
        public string Value3 { get; set; }
    }
    

    你又想映射到以下目标类型:

     public class Destination
    {
        public int Value1 { get; set; }
        public DateTime Value2 { get; set; }
        public Type Value3 { get; set; }
    }
    

    如果我们尝试直接映射这两种类型, AutoMapper 将抛出一个异常 (在执行映射时和配置检查时), 因为AutoMapper不知道从stringintDateTimeType的该如何映射。 要为这些类型创建映射,我们必须提供自定义类型转换器,我们有以下三种方法:

    void ConvertUsing(Func<TSource, TDestination> mappingFunction);
    void ConvertUsing(ITypeConverter<TSource, TDestination> converter);
    void ConvertUsing<TTypeConverter>() where TTypeConverter : ITypeConverter<TSource, TDestination>;
    

    第一种方法是写一个委托来指定如何转换源类型到目标类型。如

    cfg.CreateMap<string,int>().ConvertUsing(s=>Convert.ToInt32(s));
    

    这种方法只能处理简单类型的情况,针对复合类型的情况我们需要创建自定义的ITypeConverter<TSource, TDestination>转换器:

    public interface ITypeConverter<in TSource, TDestination>
    {
        TDestination Convert(TSource source, TDestination destination, ResolutionContext context);
    }
    

    AutoMapper提供自定义类型转换器的实例,或者只提供类型,AutoMapper将在运行时实例化。然后,上面的源/目标类型的映射配置变为:

    [Test]
    public void Example()
    {
        Mapper.Initialize(cfg => {
          cfg.CreateMap<string, int>().ConvertUsing(s => Convert.ToInt32(s));
          cfg.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
          cfg.CreateMap<string, Type>().ConvertUsing<TypeTypeConverter>();
          cfg.CreateMap<Source, Destination>();
        });
        Mapper.AssertConfigurationIsValid();
    
        var source = new Source
        {
            Value1 = "5",
            Value2 = "01/01/2000",
            Value3 = "AutoMapperSamples.GlobalTypeConverters.GlobalTypeConverters+Destination"
        };
    
        Destination result = Mapper.Map<Source, Destination>(source);
        result.Value3.ShouldEqual(typeof(Destination));
    }
    
    public class DateTimeTypeConverter : ITypeConverter<string, DateTime>
    {
        public DateTime Convert(string source, DateTime destination, ResolutionContext context)
        {
            return System.Convert.ToDateTime(source);
        }
    }
    
    public class TypeTypeConverter : ITypeConverter<string, Type>
    {
        public Type Convert(string source, Type destination, ResolutionContext context)
        {
              return Assembly.GetExecutingAssembly().GetType(source);
        }
    }
    

    在第一个映射中,从string到Int32,我们只使用内置的Convert.ToInt32函数。
    接下来的两个映射使用了自定义ITypeConverter实现。

    自定义类型转换器的真正强大的地方在于,AutoMapper可以在任何源/目标类型上使用它们。我们可以在使用其他映射配置上方构建一组自定义类型转换器,而无需任何额外配置。在上面的例子中,我们永远不需要再次指定string/int 转换。如果必须在类型成员级别配置自定义值解析器,则自定义类型转换器的范围是全局的。

    系统类型转换器

    .NETFramework 通过TypeConverter类支持类型转换器的概念。AutoMapper 在配置检查和映射时支持这些类型的类型转换器,而且不需要手动配置。AutoMappe通过使用TypeDescriptor.GetConverter方法确定源/目标类型是否可映射。

  • 相关阅读:
    MapReduce的工作机制
    1023. Have Fun with Numbers (20)
    Javascript MVC 学习笔记(二) 控制器和状态
    Chapter 1 Securing Your Server and Network(5):使用SSL加密会话
    《MySQL必知必会学习笔记》:子查询
    C# 打开指定的目录 记住路径中 / 与 的使用方法
    JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对照
    应届生面试准备之道
    一致性hash
    android 关于listview scrollview 底部 控件无法显示的两个解决方案
  • 原文地址:https://www.cnblogs.com/zengpeng/p/11059911.html
Copyright © 2011-2022 走看看