配置 Configuration
通过构造函数来创建 MapperConfiguration
实例, 以及初始化配置.
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<Foo, Bar>();
cfg.AddProfile<FooProfile>();
});
MapperConfiguration
实例可以存储到静态字段中, 或存储在依赖注入容器中. 一旦创建不允许修改.
从 9.0 开始不再支持静态 API.
Profile
实例
有一个管理配置的好方法, 就是使用 Profile
类, 派生它, 然后将配置写在构造函数中.
// 该方法从第 5 版开始被支持
public class OrganizationProfile: Profile {
public OrganizationProfile() {
CreateMap<Foo, FooDto>();
// 这里使用 `CreateMap` 等方法. Profile 的方法与 Configuration 方法一样.
}
}
// 4.x 的使用办法, 已废除
// public class OrganizationProfile: Profile {
// protected override void Configure() {
// CreateMap<Foo, FooDto>();
// }
// }
早期版本中使用 Configure
方法, 在第 5 版中不再推荐使用, 第 6 版中将会被移除.
profile 中的 configuration 只会作用 profile 中的映射. 全局 configuration 中的配置, 会作用所有创建的 map.
这一句翻译云云不知何谓. 原文如下:
Configuration inside a profile only applies to maps inside the profile. Configuration applied to the root configuration applies to all maps created.
好像了解什么意思了.
搜素程序集与自动配置
有很多种方式加载 Profile, 例如直接法:
cfg.AddProfile<OrganizationProfile>();
cdg.AddProfile(new OrganizationProfile());
或者使用自动搜素
// 搜素程序集中的所有 profile
// 使用实例方法
var config = new MapperConfiluration(cfg => {
cfg.AddMaps(myAssembly);
});
// 也可以使用程序集名字
var configuration = new MapperConfiguration(
cfg => cfg.AddMaps(new [] {
"Foo.UI",
"Foo.Core"
})
);
// 或使用程序集类型
var config = new MapperConfiguration(cfg => {
cfg.AddMaps(new [] {
typeof(HomeController),
typeof(Entity)
})
});
AutoMapper
会自动扫描程序集中, 派生自 Profile
的类, 并加载他们的配置.
命名约定
你可以设置源类型与目标类型的命名约定
var configuration = new MapperConfiguration(cfg => {
cfg.SourceMemberConvention = LowerUnderscoreNamingConvention.Instance;
cfg.DestinationMemberConvention = PascalCaseNamingConvention.Instance;
});
这样会构造如此映射: property_name -> PropertyName
.
你也可以为每一个 profile 来设置:
public class ...Profile: Profile {
public ...Profile() {
SourceMemberConvention = LowerUnderscoreNamingConvention.Instance;
DestinationMemberConvention = PascalCaseNamingConvention.Instance;
}
}
如果不需要命名约定, 可以使用 ExactMatchNamingConvention
.
这些
Convention
的具体含义有待确认. 以及还有多少Convention
.
替换字符 (简略)
定义属性名构成的字符集的映射. 例如, 将带有重音符号的属性名, 映射到无中音符号的.
C# 采用 Unicode 字符集进行编码, 可以支持很多字符集.
其核心便是, 调用 ReplaceMemberName("源字符串", "目标字符串")
来实现转换. 例如:
var configuration = new MapperConfiguration(c => {
c.ReplaceMemberName("Ä", "A");
c.ReplaceMemberName("í", "i");
c.ReplaceMemberName("Airlina", "Airline");
});
配置前后缀(简略)
与字符串替换类似. 有些属性名, 带有一些前后缀, 必要时需要将其移除或替换.
例如需要: frmValue -> Value
, 则可以
var config = new MapperConfiguration(cfg => {
cfg.RecognizePrefixes("frm");
cfg.CreateMap<Source, Dest>();
});
AutoMapper
会识别 Get
前缀, 如果要清除可以使用:
var conf = new MapperConfiguration(cfg => {
cfg.ClearPrefixes();
cfg.RecognizePrefixes("frm");
});
全局属性/字段过滤
默认情况下, 映射所有 public 属性/字段. 可以自行配置是否映射:
var config = new MapperConfiguration(cfg => {
// 不映射所有的字段
cfg.ShouldMapField = fi => false;
// 映射含有 public, private gatter 的属性
cfg.ShouldMapProperty = pi =>
pi.GetMethod != null && (pi.GetMethod.IsPublic || pi.GetMethod.IsPrivate);
})
配置可见性
默认仅仅映射 public 的属性与字段, 如果需要调整可见性, 可以进行配置. 例如:
var conf = new MapperConfiguration(cfg => {
// 映射具有 public 和 internal getter 的属性
cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly
});
配置编译
由于表达式编译需要占用一定资源, 因此 AutoMapper
默认采用延迟编译, 在使用的时候才会编译. 可以配置其直接编译:
var conf = new MapperConfiguration(cfg => {});
conf.CompileMappings();
对于数以百计的映射, 这个过程会耗费一定时间.
编译时长
随时间与映射数量的变化, 编译会消耗的时间也会逐步增长. 一般建议调整 DTO 的大小, 尽可能让其更小, 适应某一特定厂家. 也可以配置执行计划的大小, 而不需修改类.
你可以设置每一个成员的 MapAtRuntime
或全局的 MaxExecutionPlanDepth
(默认是1, 修改为0).
如此编译会更快, 但映射会变慢.