创建一个MapperConfiguration
实例并通过构造函数初始化配置:
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<Foo, Bar>();
cfg.AddProfile<FooProfile>();
});
MapperConfiguration
实例可以静态存储在一个静态字段中,也可以存储在一个依赖注入容器中。 一旦创建,不能更改/修改。
或者,您可以使用静态Mapper
实例来初始化AutoMapper
:
Mapper.Initialize(cfg => {
cfg.CreateMap<Foo, Bar>();
cfg.AddProfile<FooProfile>();
});
配置文件实例
组织您的映射配置的一个好方法是使用配置文件。 创建从配置文件继承的类,并将配置放置在构造函数中:
//这是从版本5开始的方法
public class OrganizationProfile : Profile
{
public OrganizationProfile()
{
CreateMap<Foo, FooDto>();
// 使用CreateMap ...等等。这里(配置文件方法与配置方法相同)
}
}
// 4.x是如何完成的 - 从5.0开始已经过时了:
// public class OrganizationProfile : Profile
// {
// protected override void Configure()
// {
// CreateMap<Foo, FooDto>();
// }
// }
在早期版本中,使用配置方法而不是构造函数。 从版本5开始,Configure()
已经过时。 它将在6.0中被删除。
配置文件中的配置仅适用于配置文件中的映射。 应用于根配置的配置适用于所有创建的映射。
程序集扫描自动配置
配置文件可以通过多种方式添加到主映射器配置中,可以直接:
cfg.AddProfile<OrganizationProfile>();
cfg.AddProfile(new OrganizationProfile());
或通过自动扫描配置文件:
//扫描程序集中的所有配置文件
//...使用实例方法:
var config = new MapperConfiguration(cfg => {
cfg.AddProfiles(myAssembly);
});
// ...或静态方法:
Mapper.Initialize(cfg => cfg.AddProfiles(myAssembly));
//也可以使用程序集名称:
Mapper.Initialize(cfg =>
cfg.AddProfiles(new [] {
"Foo.UI",
"Foo.Core"
});
);
//或程序集的标记类型:
Mapper.Initialize(cfg =>
cfg.AddProfiles(new [] {
typeof(HomeController),
typeof(Entity)
});
);
AutoMapper将扫描指定的程序集,以继承从配置文件继承的类,并将其添加到配置中。
命名约定
您可以设置源和目标命名约定
Mapper.Initialize(cfg => {
cfg.SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();
cfg.DestinationMemberNamingConvention = new PascalCaseNamingConvention();
});
这会将以下属性映射到对方:property_name -> PropertyName
您也可以在每个配置文件级别进行设置
public class OrganizationProfile : Profile
{
public OrganizationProfile()
{
SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();
DestinationMemberNamingConvention = new PascalCaseNamingConvention();
//Put your CreateMap... Etc.. here
}
}
替换字符
您还可以在成员名称匹配期间替换源成员中的单个字符或整个单词:
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; }
}
我们要替换个别字符,也许转换一个单词:
Mapper.Initialize(c =>
{
c.ReplaceMemberName("Ä", "A");
c.ReplaceMemberName("í", "i");
c.ReplaceMemberName("Airlina", "Airline");
});
识别前/后缀
有时你的源/目标属性会有共同的前/后缀,导致你必须做一堆自定义成员映射,因为名称不匹配。 为了解决这个问题,你可以识别前/后缀:
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; }
}
Mapper.Initialize(cfg => {
cfg.RecognizePrefixes("frm");
cfg.CreateMap<Source, Dest>();
});
Mapper.AssertConfigurationIsValid();
默认情况下,AutoMapper
可以识别前缀“Get”
,如果需要清除前缀:
Mapper.Initialize(cfg => {
cfg.ClearPrefixes();
cfg.RecognizePrefixes("tmp");
});
全局属性/字段过滤
默认情况下,AutoMapper
尝试映射每个公共属性/字段。 您可以使用属性/字段过滤器过滤出属性/字段:
Mapper.Initialize(cfg =>
{
//不要映射任何字段
cfg.ShouldMapField = fi => false;
// map properties with a public or private getter
//映射 公共或私有访问器的属性
cfg.ShouldMapProperty = pi =>
pi.GetMethod != null && (pi.GetMethod.IsPublic || pi.GetMethod.IsPrivate);
});
配置可见性
默认情况下,AutoMapper
只识别公共成员。 它可以映射到私有设置器,但如果整个属性是私人/内部的,则会跳过内部/私有方法和属性。 要指示AutoMapper
识别具有其他可见性的成员,请覆盖默认过滤器ShouldMapField
和/或ShouldMapProperty
:
Mapper.Initialize(cfg =>
{
// map properties with public or internal getters
cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
cfg.CreateMap<Source, Destination>();
});
映射配置现在可以识别内部/私人成员。
配置编译
由于表达式编译可能会占用大量资源,因此AutoMapper
会在第一个映射上编译类型映射计划。 但是,这种行为并不总是可取的,所以你可以告诉AutoMapper
直接编译它的映射:
Mapper.Initialize(cfg => {});
Mapper.Configuration.CompileMappings();
对于几百个映射,这可能需要几秒钟的时间。
重置静态映射配置
静态Mapper.Initialize
只能被调用一次。 重置静态映射配置(例如,在测试开始时):
Mapper.Reset();
Mapper.Initialize(cfg => { /* 再次配置 */ });
生产代码中不应该使用重置。 它旨在仅支持测试场景。