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方法确定源/目标类型是否可映射。

  • 相关阅读:
    JavaScript cookie详解
    Javascript数组的排序:sort()方法和reverse()方法
    javascript中write( ) 和 writeln( )的区别
    div做表格
    JS 盒模型 scrollLeft, scrollWidth, clientWidth, offsetWidth 详解
    Job for phpfpm.service failed because the control process exited with error code. See "systemctl status phpfpm.service" and "journalctl xe" for details.
    orm查询存在价格为空问题
    利用救援模式破解系统密码
    SSH服务拒绝了密码
    C# 调用 C++ DLL 中的委托,引发“对XXX::Invoke类型的已垃圾回收委托进行了回调”错误的解决办法
  • 原文地址:https://www.cnblogs.com/zengpeng/p/11059911.html
Copyright © 2011-2022 走看看