如何使用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。

相关推荐
七夜zippoe8 天前
Spring与MyBatis整合原理及事务管理
java·spring·mybatis·事务·mapper
七夜zippoe10 天前
MyBatis核心源码解析 从SqlSession到Mapper接口的绑定过程
java·mybatis·mapper·sqlsession·缓存机制
xiangji3 个月前
PocoEmit遥遥领先于AutoMapper之循环引用
automapper·mapper·emit
阿里嘎多哈基米4 个月前
SQL 层面行转列
数据库·sql·状态模式·mapper·行转列
xiangji4 个月前
微软.net表达式编译居然有bug?
表达式·expression·emit
xiangji4 个月前
PocoEmit字典增强功能
mapper·emit·类型转化
胡斌附体7 个月前
vue父子组件通信的使用, 跟新v-model
vue·v-model·使用场景·emit·子父组件通信·change事件
abcnull7 个月前
mybatis的mapper对应的xml写法
xml·sql·spring·mybatis·mapper
Heaven6451 年前
Mapper代理开发
java·mybatis·mapper·代理开发