• 2.1配置(AutoMapper官方文档翻译)


    Configuration

    创建一个MapperConfiguration实例并通过构造函数初始化配置:

    var config = new MapperConfiguration(cfg => {
        cfg.CreateMap<Foo, Bar>();
        cfg.AddProfile<FooProfile>();
    });
    
    • 1
    • 2
    • 3
    • 4

    MapperConfiguration实例可以静态地存储在静态字段或依赖注入容器中。一旦创建,就不能更改/修改。

    var configuration = new MapperConfiguration(cfg => {
        cfg.CreateMap<Foo, Bar>();
        cfg.AddProfile<FooProfile>();
    });
    
    • 1
    • 2
    • 3
    • 4

    从9.0开始,静态API不再可用。

    配置文件(Profile)实例

    使用配置文件是组织映射配置的一个良好实践。创建一个从Profile继承的类,并将配置放入构造函数中:

    // 这是从版本5开始的方法
    public class OrganizationProfile : Profile
    {
    	public OrganizationProfile()
    	{
    		CreateMap<Foo, FooDto>();
    		// 在这使用CreateMap...等(Profile方法与configuration方法相同)
    	}
    }
    
    // 这是已经废弃了的用于版本 4.x - 到 5.0 的方法:
    // public class OrganizationProfile : Profile
    // {
    //     protected override void Configure()
    //     {
    //         CreateMap();
    //     }
    // }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在早期版本中,使用Configure方法代替构造函数。从版本5开始,Configure()已经过时了。它将在6.0中被删除。

    配置文件中的配置只适用于配置文件中的映射。应用于根配置的配置将应用于创建的所有映射。

    程序集扫描的自动配置

    配置文件可以通过多种方式添加到主映射器配置中,或者直接添加:

    cfg.AddProfile<OrganizationProfile>();
    cfg.AddProfile(new OrganizationProfile());
    
    • 1
    • 2

    或者通过自动扫描配置文件:

    // 扫描程序集中所有的 profiles 
    // 通过使用程序集实体的:
    var config = new MapperConfiguration(cfg => {
        cfg.AddMaps(myAssembly);
    });
    var configuration = new MapperConfiguration(cfg => cfg.AddMaps(myAssembly));
    
    // 通过使用程序集的名称:
    var configuration = new MapperConfiguration(cfg =>
        cfg.AddMaps(new [] {
            "Foo.UI",
            "Foo.Core"
        });
    );
    
    // Or marker types for assemblies:
    var configuration = new MapperConfiguration(cfg =>
        cfg.AddMaps(new [] {
            typeof(HomeController),
            typeof(Entity)
        });
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    AutoMapper将扫描指定的程序集,查找从Profile继承的类,并将它们添加到配置中。

    命名约定(Naming Conventions)

    可以设置源和目标命名约定

    var configuration = new MapperConfiguration(cfg => {
      cfg.SourceMemberNamingConvention = LowerUnderscoreNamingConvention.Instance;
      cfg.DestinationMemberNamingConvention = PascalCaseNamingConvention.Instance;
    });
    
    • 1
    • 2
    • 3
    • 4

    这将把以下属性相互映射:
    property_name -> PropertyName
    您也可以设置每个配置文件

    public class OrganizationProfile : Profile
    {
      public OrganizationProfile()
      {
        SourceMemberNamingConvention = LowerUnderscoreNamingConvention.Instance;
        DestinationMemberNamingConvention = PascalCaseNamingConvention.Instance;
        //Put your CreateMap... Etc.. here
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果不需要命名约定,可以使用
    ExactMatchNamingConvention

    替换字符

    还可以在成员名匹配期间替换源成员中的单个字符或整个单词:

    public class Source
    {
        public int Value { get; set; }
        public int Ävíator { get; set; }
        public int SubAirlinaFlight { get; set; }
    }
    public class Destination
    {
        public int Value { get; set; }
        public int Aviator { get; set; }
        public int SubAirlineFlight { get; set; }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    我们想要替换单个字符,或者翻译一个单词:

    var configuration = new MapperConfiguration(c =>
    {
        c.ReplaceMemberName("Ä", "A");
        c.ReplaceMemberName("í", "i");
        c.ReplaceMemberName("Airlina", "Airline");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    识别前/后缀

    有时源/目标属性会有共同的前缀/后缀,这会导致不得不做一堆自定义成员映射,因为名字不匹配。为了解决这个问题,可以识别前缀/后缀:

    public class Source {
        public int frmValue { get; set; }
        public int frmValue2 { get; set; }
    }
    public class Dest {
        public int Value { get; set; }
        public int Value2 { get; set; }
    }
    var configuration = new MapperConfiguration(cfg => {
        cfg.RecognizePrefixes("frm");
        cfg.CreateMap<Source, Dest>();
    });
    configuration.AssertConfigurationIsValid();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    默认情况下,AutoMapper识别前缀" Get ",如果你需要清除前缀:

    var configuration = new MapperConfiguration(cfg => {
        cfg.ClearPrefixes();
        cfg.RecognizePrefixes("tmp");
    });
    
    • 1
    • 2
    • 3
    • 4

    配置的可见性

    默认情况下,AutoMapper只识别public成员。它可以映射到私有setter,但如果整个属性都是私有/内部的,它将跳过内部/私有方法和属性。要指示AutoMapper识别具有其他可见性的成员,覆盖默认过滤器ShouldMapField和/或Shouldmproperty:

    var configuration = new MapperConfiguration(cfg =>
    {
        // map properties with public or internal getters
        cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
        cfg.CreateMap<Source, Destination>();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Map配置现在将识别内部/私有成员。

    配置编译

    因为表达式编译可能会占用一些资源,所以AutoMapper会在第一个映射上惰性地编译类型映射计划(译者注:调用的时候才编译映射)。然而,这种行为并不总是理想的,所以你可以告诉AutoMapper直接编译它的映射:

    var configuration = new MapperConfiguration(cfg => {});
    configuration.CompileMappings();
    
    • 1
    • 2

    对于几百个映射,这可能需要几秒钟。如果花费的时间太长,可能是你有一些非常大的执行计划。

    编译时间长

    编译时间随着执行计划的大小而增加,这取决于属性的数量及其复杂性。理想情况下,您将修复您的模型,以便您有许多小型的DTO,每个DTO针对一个特定的用例。但是您也可以在不更改类的情况下减小执行计划的大小。

    你可以给每个成员全局地设置MapAtRuntimeMaxExecutionPlanDepth(默认为1,将它设置为零)。

    这将通过用方法调用替换子对象的执行计划来减小执行计划的大小。编译会更快,但映射本身可能会更慢。搜索repo以获得更多细节,并使用分析器(profiler )来更好地理解效果。避免使用PreserveReferencesMaxDepth也有帮助。

    原文链接

    译者代码实现

    github仓库地址
    gitee仓库地址

  • 相关阅读:
    18.Raising and Lower Indexs
    对象的比较(下)
    阿里面试题:强、软、弱、虚引用的特点及应用场景
    GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图
    sonarqube二次安装启动报错解决方法
    基于Java的旅游网站系统设计与实现(源码+lw+部署文档+讲解等)
    项目管理之Scrum
    Go 实现插入排序算法及优化
    DOM—节点操作
    【★★★★★ 树与二叉树总结笔记 2022 9.5】
  • 原文地址:https://blog.csdn.net/yan_yu_lv_ji/article/details/133581352