如何使用PocoEmit.Mapper替代AutoMapper

PocoEmit使用比较简单对于大部分转化是不需要手动配置

可以替代AutoMapper的大部分工作,实现精简代码,提高性能

一、简单类型转化无需配置

什么样的类型转化对PocoEmit来说是简单的呢

1. 基础类型、枚举互转

csharp 复制代码
int intValue =  PocoEmit.Mapper.Default.Convert<string, long>("123");
long longValue =  PocoEmit.Mapper.Default.Convert<int, long>(123);
strting stringValue =  PocoEmit.Mapper.Default.Convert<int, string>(123);
csharp 复制代码
public enum MyColor
{
    None = 0,
    Red = 1,
    Green = 2,
    Blue = 3,
}
ConsoleColor color = ConsoleColor.DarkBlue;
// Red
MyColor redColor = PocoEmit.Mapper.Default.Convert<ConsoleColor, MyColor>(ConsoleColor.Red);
string colorName =  PocoEmit.Mapper.Default.Convert<ConsoleColor, string>(ConsoleColor.Red);
// 1
long colorValue =  PocoEmit.Mapper.Default.Convert<MyColor, long>(MyColor.Red);
/ None
MyColor noneColor = PocoEmit.Mapper.Default.Convert<ConsoleColor, MyColor>(ConsoleColor.DarkBlue);

2. 可空类型转化

csharp 复制代码
int intValue =  PocoEmit.Mapper.Default.Convert<string?, long>("123");
long? longValue =  PocoEmit.Mapper.Default.Convert<int, long?>(123);
strting stringValue =  PocoEmit.Mapper.Default.Convert<int?, string>(123);
User user = PocoEmit.Mapper.Default.Convert<User?, User>(null);

3. 构造函数和属性互转

csharp 复制代码
class MyId(int id)
{
    public int Id { get; } = id;
}
class MyId2(int? id)
{
    public int? Id { get; } = id;
}

3.1 构造函数转化

csharp 复制代码
var myId = PocoEmit.Mapper.Default.Convert<int, MyId>(1);
var myId2 = PocoEmit.Mapper.Default.Convert<int?, MyId2>(2);
var myId3 = PocoEmit.Mapper.Default.Convert<int?, MyId>(3);
var myId4 = PocoEmit.Mapper.Default.Convert<int, MyId2>(4);

3.2 属性转化

csharp 复制代码
var id = PocoEmit.Mapper.Default.Convert<MyId, int>(new MyId(1));
var id2 = PocoEmit.Mapper.Default.Convert<MyId2, int?>(new MyId2(2));
var id3 = PocoEmit.Mapper.Default.Convert<MyId, int?>(new MyId(3));
var id4 = PocoEmit.Mapper.Default.Convert<MyId2, int>(new MyId2(4));

4. 复合类型同名属性互转

csharp 复制代码
var dto =  PocoEmit.Mapper.Default.Convert<User, UserDTO>(new User { Id = 1, Name = "Jxj1" });
var user =  PocoEmit.Mapper.Default.Convert<UserDTO, User>(new UserDTO { Id = 2, Name = "Jxj2" });
var user3 =  PocoEmit.Mapper.Default.Convert<UserDTO2, User>(new UserDTO { Id = "3", Name = "张三" });

二、一键开启集合类型转化配置

  • 通过UseCollection扩展方法给PocoEmit.Mapper增加集合功能
  • 扩展后PocoEmit.Mapper支持集合(含数组、列表及字典)的转化和复制
  • 支持实体类型包含集合成员的转化和复制

1. 启用集合配置

1.2 开启全局集合配置

  • 对所有Mapper启用集合
  • 应在使用所有Mapper实例之前配置,对已经完成初始化的Mapper实例无效
csharp 复制代码
CollectionContainer.GlobalUseCollection();

1.1 对单个Mapper启用集合

csharp 复制代码
PocoEmit.Mapper.UseCollection();

2.启用集合后集合互转无需配置

csharp 复制代码
User[] source = [new User { Id = 1, Name = "Jxj" }, new User { Id = 2, Name = "张三" }];
UserDTO[] result = PocoEmit.Mapper.Default.Convert<User[], UserDTO[]>(source);
csharp 复制代码
IEnumerable<User> source = [new User { Id = 1, Name = "Jxj" }, new User { Id = 2, Name = "张三" }];
UserDTO[] result = PocoEmit.Mapper.Default.Convert<IEnumerable<User>, UserDTO[]>(source);
csharp 复制代码
User[] source = [new User { Id = 1, Name = "Jxj" }, new User { Id = 2, Name = "张三" }];
IEnumerable<UserDTO> result = _mapper.Convert<User[], IEnumerable<UserDTO>>(source);
csharp 复制代码
Dictionary<int, User> source = new() { { 1, new User { Id = 1, Name = "Jxj" } } };
UserDTO[] result = _mapper.Convert<Dictionary<int, User>, UserDTO[]>(source);
csharp 复制代码
Dictionary<int, User> source = new() { { 1, new User { Id = 1, Name = "Jxj" } } };
Dictionary<int, UserDTO> result = _mapper.Convert<Dictionary<int, User>, Dictionary<int, UserDTO>>(source);

3.启用集合后集合成员互转无需配置

csharp 复制代码
var source = new UserArray { Name = "VIP", Users = [new User { Id = 1, Name = "Jxj" }, new User { Id = 2, Name = "张三" }] };
UserDTOArray result = _mapper.Convert<UserArray, UserDTOArray>(source);

三、自定义配置

1. Mapper全局配置

  • 全局配置对所有Mapper适用
  • 全局配置应在使用所有Mapper实例之前配置,对已经完成初始化的Mapper实例无效

1.1 全局配置映射规则

csharp 复制代码
PocoEmit.Mapper.GlobalConfigure(mapper => {
    mapper.ConfigureMap<User, UserDTO>()
    .Source
    .Ignore(nameof(User.Name));
});

1.2 全局配置内部缓存字典大小

  • 配置适当大小可以减少内存占用和扩容
csharp 复制代码
Mapper.GlobalOptions(options => {
    // 转化器数量
    options.ConverterCapacity = 100;
});

2. 配置单个Mapper

csharp 复制代码
PocoEmit.Mapper.Default.ConfigureMap<User, UserDTO>()
    .Source
    .Ignore(nameof(User.Name));;

3. 哪些需要配置

3.1 属性名前、后缀

  • AddPrefix设置前缀
  • AddSuffix设置后缀
  • ClearPrefix清空前缀
csharp 复制代码
public class UserCustomDTO(string userName)
{
    public int? UId { get; set; }
    public string UName { get; } = userName;
}
3.1.1 源类型设置前缀
csharp 复制代码
IMapper mapper = Mapper.Create();
mapper.ConfigureMap<UserCustomDTO, User>()
    .Source
    .AddPrefix("U");
var source = new UserCustomDTO("Jxj2") { UId = 222 };
var converter = mapper.GetConverter<UserCustomDTO, User>();
User result = converter.Convert(source);
3.1.2 目标类型源设置前缀
csharp 复制代码
IMapper mapper = Mapper.Create();
mapper.ConfigureMap<User, UserCustomDTO>()
    .Dest
    .AddPrefix("U");
var source = new User { Id = 222, Name = "Jxj2" };
var result = mapper.Convert<User, UserCustomDTO>(source);
3.1.3 默认前缀
  • ConfigureMap会默认把源类型名作为目标类型前缀
  • ConfigureMap会默认把目标类型名作为源类型前缀
  • 如果默认前缀干扰到正常匹配,可以调用ClearPrefix清空前缀
csharp 复制代码
public class AutoUserDTO
{
    public string UserId { get; set; }
    public string UserName { get; set; }
}
IMapper mapper = Mapper.Create();
mapper.ConfigureMap<AutoUserDTO, User>();
var source = new AutoUserDTO{ UserId = "222", UserName = "Jxj"  };
var converter = mapper.GetConverter<AutoUserDTO, User>();
User result = converter.Convert(source);

3.2 属性一对一配置

3.2.1 通过Source配置
  • 直接MapTo或ForMember
csharp 复制代码
IMapper mapper = Mapper.Create();
mapper.ConfigureMap<User, UserCustomDTO>()
    .Source
    .MapTo(nameof(User.Id), nameof(UserCustomDTO.UId))
    .MapTo(nameof(User.Name), nameof(UserCustomDTO.UName));
var source = new User { Id = 222, Name = "Jxj2" };
var converter = mapper.GetConverter<User, UserCustomDTO>();
UserCustomDTO result = converter.Convert(source);
csharp 复制代码
IMapper mapper = Mapper.Create();
mapper.ConfigureMap<User, UserCustomDTO>()
    .Source
    .ForMember(nameof(User.Id)).MapTo(nameof(UserCustomDTO.UId))
    .ForMember(nameof(User.Name)).MapTo(nameof(UserCustomDTO.UName));
var source = new User { Id = 222, Name = "Jxj2" };
var converter = mapper.GetConverter<User, UserCustomDTO>();
UserCustomDTO result = converter.Convert(source);
3.2.2 通过Dest配置
  • 直接MapFrom或ForMember
csharp 复制代码
IMapper mapper = Mapper.Create();
mapper.ConfigureMap<UserCustomDTO, User>()
    .Dest
    .MapFrom(nameof(User.Id), nameof(UserCustomDTO.UId))
    .MapFrom(nameof(User.Name), nameof(UserCustomDTO.UName));
var source = new UserCustomDTO("Jxj2") { UId = 222 };
var converter = mapper.GetConverter<UserCustomDTO, User>();
User result = converter.Convert(source);
csharp 复制代码
IMapper mapper = Mapper.Create();
mapper.ConfigureMap<UserCustomDTO, User>()
    .Dest
    .ForMember(nameof(User.Id)).MapFrom(nameof(UserCustomDTO.UId))
    .ForMember(nameof(User.Name)).MapFrom(nameof(UserCustomDTO.UName));
var source = new UserCustomDTO("Jxj2") { UId = 222 };
var converter = mapper.GetConverter<UserCustomDTO, User>();
User result = converter.Convert(source);

源码托管地址: https://github.com/donetsoftwork/MyEmit ,也欢迎大家直接查看源码。

gitee同步更新:https://gitee.com/donetsoftwork/MyEmit

如果大家喜欢请动动您发财的小手手帮忙点一下Star。

相关推荐
胡斌附体2 个月前
vue父子组件通信的使用, 跟新v-model
vue·v-model·使用场景·emit·子父组件通信·change事件
abcnull3 个月前
mybatis的mapper对应的xml写法
xml·sql·spring·mybatis·mapper
Heaven64510 个月前
Mapper代理开发
java·mybatis·mapper·代理开发
bestcxx1 年前
019、子组件向父组件传递参数 this.$emit
vue·emit·子组件传递参数·向父组件传递参数
码农爱java1 年前
MyBatis 源码分析-- getMapper(获取Mapper)
mybatis·源码·mapper·sqlsession·getmapper
路过秋天1 年前
.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)
.net·emit·il指令
Davieyang.D.Y1 年前
互联网轻量级框架整合之MyBatis核心组件
mybatis·生命周期·mapper·sqlsession·sessionfactory
路过秋天1 年前
.NET Emit 入门教程:第六部分:IL 指令:8:详解 ILGenerator 指令方法:类型转换指令
emit·net
路过秋天1 年前
.NET Emit 入门教程:第六部分:IL 指令:7:详解 ILGenerator 指令方法:分支条件指令
emit·net