当前位置:网站首页>C# Mapster 对象映射器学习
C# Mapster 对象映射器学习
2022-06-21 17:37:00 【煮吧姐】
安装 Mapster
PM> Install-Package Mapster
或者 dotnet add package Mapster
定义实体
目的:使用 Mapster 实现 User 到 UserDto 的映射
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
public string like { get; set; }
}
public class UserDto
{
public string name { get; set; }
public int UserAge { get; set; }
public string UserSex { get; set; }
public string like { get; set; }
}
简单使用
/*
* 默认情况下,无需任何配置,Mapster会根据两个实体字段名称相同进行匹配
* 第一次调用时,配置会被缓存,第二次将会从缓存中取,以此提升性能
*/
var user = new User();
var dto = user.Adapt<UserDto>();//映射为新对象
user.Adapt(dto);//在目标对象的基础上进行映射
//注意:Adapt扩展方法使用的配置为 `TypeAdapterConfig.GlobalSettings`
Mapster 配置 (TypeAdapterConfig)
可以直接使用 Mapster 内置的全局静态配置 TypeAdapterConfig.GlobalSettings
,也可以实例化一个配置 new TypeAdapterConfig()
推荐使用实例化的方式,对 TypeAdapterConfig 进行映射配置。
注:Mapster 默认匹配规则是相同字段名之间进行映射。
方式一
直接在 TypeAdapterConfig 配置对象的映射关系
var config = new TypeAdapterConfig();
//映射规则
config.ForType<User, UserDto>()
.Map(dest => dest.UserAge, src => src.Age)
.Map(dest => dest.UserSex, src => src.Sex);
var mapper = new Mapper(config);//务必将mapper设为单实例
var user = new User{Name = "xiaowang",Age = 18,Sex = "boy"};
var dto = mapper.Map<UserDto>(user);
字段带有前后缀,可以使用 NameMatchingStrategy.ConvertDestinationMemberName
对目标字段名称进行替换,使得它和源字段名称相同。
还有替换源字段的方法NameMatchingStrategy.ConvertSourceMemberName
注意:如果一个
ForType
定义多个NameMatchingStrategy
,后定义的会覆盖先定义的规则,所以只有最后定义的规则会生效
var config = new TypeAdapterConfig();
//使用
config.ForType<User, UserDto>()
.NameMatchingStrategy(NameMatchingStrategy.ConvertDestinationMemberName(dest => dest.Replace("User", "")));
方式二
使用接口的方式,需要实现 IRegister
//实现接口 IRegister
public class UserDtoRegister : IRegister
{
public void Register(TypeAdapterConfig config)
{
config.ForType<User,UserDto>()
Map(dest => dest.UserAge, src => src.Age);
//...
}
}
//实例化Mapper
var config = new TypeAdapterConfig();
//var config = TypeAdapterConfig.GlobalSettings;
//只有要给定 IRegister 所在的程序集名称,Mapster 会自动识别 IRegister,进行配置注入。
config.Scan("程序集名称1","程序集名称2");
var mapper = new Mapper(config);//务必设置为单实例
忽略字段
var config = new TypeAdapterConfig();
//映射规则
config.ForType<User, UserDto>()
.Map(dest => dest.UserAge, src => src.Age)
.Map(dest => dest.UserSex, src => src.Sex);
.IgnoreNullValues(true)//忽略空值映射
.Ignore(dest => dest.UserAge)//忽略指定字段
.IgnoreAttribute(typeof(DataMemberAttribute))//忽略指定特性的字段
.NameMatchingStrategy(NameMatchingStrategy.IgnoreCase)//忽略字段名称的大小写
.IgnoreNonMapped(true);//忽略除以上配置的所有字段
config.ForType<User,UserDto>()
.IgnoreMember((member, side) => !member.Type.Namespace.StartsWith("System"));//实现更细致的忽略规则
member
和side
分别对应IMemberModel
和MemberSide
,这里我贴出相应的源码。
//包含了映射类型的信息
public interface IMemberModel
{
Type Type { get; }
string Name { get; }
object? Info { get; }
AccessModifier SetterModifier { get; }
AccessModifier AccessModifier { get; }
IEnumerable<object> GetCustomAttributes(bool inherit);
}
//标识当前是源类型还是目标类型
public enum MemberSide
{
Source = 0,
Destination = 1
}
分支(Fork)
Mapster 的 Fork 功能允许我们定义局部的映射规则,并且分支不会重复编译,不需要考虑性能问题。
var config = new TypeAdapterConfig();
var mapper = new Mapper(config);
var user = new User{Name = "xiaowang",Age = 18,Sex = "boy"};
var dto = mapper.From(user).ForkConfig(forked =>
{
//该分支规则,不会重复编译,仅限该语句中有效,不会影响config的配置
forked.ForType<User, UserDto>().Map(dest => dest.name, src => src.Name);
})
.AdaptToType<UserDto>();//映射为新对象
dto = mapper.From(user).ForkConfig(forked =>
{
forked.ForType<User, UserDto>().Map(dest => dest.name, src => src.Name);
})
.AdaptTo(new UserDto());//在目标对象基础上进行映射
NewConfig 方法
NewConfig 方法允许我们对两个类型之间新建配置,如果两个类型之前配置了映射关系,则 NewConfig 方法会覆盖之前的配置
var config = new TypeAdapterConfig();
config.ForType<User,UserDto>().Map(dest => dest.UserAge, src => src.Age);
//...
//覆盖 User 和 UserDto 之前的配置
config.NewConfig<User,UserDto>().Map(dest=>dest.UserAge,src=>100);
//扩展知识:覆盖Mapster默认静态配置
TypeAdapterConfig<User,UserDto>.NewConfig().Default.NameMatchingStrategy(NameMatchingStrategy.IgnoreCase);
运行时传参
允许运行时传入数据,干预映射过程
var config = new TypeAdapterConfig();
config.ForType<User, UserDto>()
.Map(dest => dest.name, src => MapContext.Current.Parameters["userName"]);//配置运行时参数
var mapper = new Mapper(config);
//使用时传入数据
var user = new User();
var dto = mapper.From(user).BuildAdapter().AddParameters("userName","xiaowang").AdaptToType<UserDto>();
其他知识点
我们尽量不要把实体间的映射规则配置到 TypeAdapterConfig.GlobalSettings
(默认配置)。随着业务的发展,一个配置很难兼顾所有业务,可能会出行冲突的情况,相对复杂的业务,可以新建一个TypeAdapterConfig
,或者使用 config.Clone()
能轻松复制一份配置。全局配置可以放一些简单的配置项,例如:映射时忽略大小写。
注意:Adapt 扩展方法使用的是
TypeAdapterConfig.GlobalSettings
小技巧
Adapt 扩展方法的使用
Dictionary<string,object> dict = new User().Adapt<Dictionary<string,object>>();//object 到 Dictionary 的转换
string s = 123.Adapt<string>(); //equal to 123.ToString();
int i = "123".Adapt<int>(); //equal to int.Parse("123");
拦截映射前后
BeforeMapping
方法和 AfterMapping
//BeforeMapping 映射执行前
config.ForType<User, UserDto>().BeforeMapping((src, dest) =>
{
src.Age = 100;
dest.UserAge = src.Age + 10;
});
//AfterMapping 映射执行后
//...
更多的使用技巧可以查看官方文档:GitHub - MapsterMapper/Mapster: A fast, fun and stimulating object to object Mapper
边栏推荐
- Niuke: merging two ordered arrays
- Get some eth from the faucet of the ropsten test network
- 华为鸿蒙认证测试题,你能答对几道?
- MySQL的MVCC实现原理
- Servlet学习(二)
- I/0多路转接之select
- 点歌系统也有鸿蒙版了?老王抢先体验了一把
- [HCTF 2018]WarmUp
- Fpga/cpld final examination paper for the first semester of Nanjing University of information technology 2020-2021
- 删除指定的screen
猜你喜欢

数据库主键一定要自增吗?有哪些场景不建议自增?

图像分类、AI 与全自动性能测试

一篇文章彻底学会画数据流图

Delete the specified screen

Canvas interactive color gradient JS special effect code

Six steps of JDBC programming

Leetcode(210)——课程表 II

In air operation, only distance mapping is used to robustly locate occluded targets (ral2022)

Product graphic list description layout style

College Physics Chapter 9 vibration
随机推荐
协同过滤(Collaborative Filtering)
A new generation of stability testing tool fastbot
R language bug? report errors? As for the outcome of sub variables 0 and 1, the original content of the outcome variable is changed through the process of factor and numeric?
How to apply for SSL certificate using IP
Servlet中Listener与Filter (监视器与拦截器)
el-table分页全选功能讲解
Blue SVG wave dynamic web page background
Delete the specified screen
equals空指针异常
homeassistant addons
牛客网:归并两个有序的数组
Leetcode(210)——课程表 II
左右两侧垂直带序号的时间轴
一篇文章彻底学会画数据流图
动态加载资源之AssetDatabase
vivo 容器集群监控系统架构与实践
蚂蚁集团自研TEE技术通过国家级金融科技产品认证 47项检测均达要求
Does the school belong to a securities company? Is it safe to open an account?
Dao与实体类的封装
文末送书 | 李航老师新作!机器学习经典著作《统计学习方法》全新升级