如何在.NET 5 Web Api中使用Mapster创建可复用的全局映射Profile
Mapster 映射配置优化方案
1. 解决配置冗余与性能问题
首先将异名字段映射抽离为独立的单源映射规则,多源映射时直接复用该规则,无需重复声明异名字段映射。Mapster的所有配置会预编译为表达式树,仅在首次调用时生成一次映射逻辑,运行时无重复遍历属性的性能损耗,即便存在大量异名字段也不会影响运行效率。
2. 全局映射Profile实现
通过实现Mapster的IRegister接口创建全局映射配置类,一次注册全局生效:
using Mapster; public class MappingProfile : IRegister { public void Register(TypeAdapterConfig config) { // 配置单源异名字段映射,后续多源映射直接复用 config.NewConfig<Todo, UsernameWithTodoTitle>() .Map(dest => dest.TodoTitle, src => src.Title); // 多源映射配置,直接复用上述单源规则 config.NewConfig<(User User, Todo Todo), UsernameWithTodoTitle>() .Map(dest => dest, src => src.User) .Map(dest => dest, src => src.Todo); } }
在.NET 5项目的Startup.cs中注册全局配置:
public void ConfigureServices(IServiceCollection services) { // 扫描当前程序集所有IRegister实现,注册映射规则 TypeAdapterConfig.GlobalSettings.Scan(System.Reflection.Assembly.GetExecutingAssembly()); services.AddControllers(); // 其他服务注册逻辑 }
3. 简化映射调用写法
通过给目标类添加静态适配方法,实现你需要的调用形式,使用partial类可以避免修改原有实体定义:
public partial class UsernameWithTodoTitle { public static UsernameWithTodoTitle Adapt((User user, Todo todo) source) { return source.Adapt<UsernameWithTodoTitle>(); } }
如果需要更通用的简化调用,也可以编写通用扩展方法:
public static class MapsterExtension { public static TDestination To<TDestination>(this object source) { return source.Adapt<TDestination>(); } } // 调用示例:var res = (user, todo).To<UsernameWithTodoTitle>();
最终使用示例
控制器内无需再写映射配置,调用逻辑非常简洁:
[ApiController] [Route("[controller]")] public class MyController : ControllerBase { [HttpGet] public ActionResult<UsernameWithTodoTitle> Get() { var user = new User { Username = "foo", FieldFromUser = "x" }; var todo = new Todo { Title = "bar", FieldFromTodo = "y" }; // 符合要求的简化调用 var usernameWithTodoTitle = UsernameWithTodoTitle.Adapt((user, todo)); return Ok(usernameWithTodoTitle); } } // 原有实体类保持不变 public class User { public string Username { get; set; } public string FieldFromUser { get; set; } } public class Todo { public string Title { get; set; } public string FieldFromTodo { get; set; } } public class UsernameWithTodoTitle { public string Username { get; set; } public string TodoTitle { get; set; } public string FieldFromUser { get; set; } public string FieldFromTodo { get; set; } }
内容的提问来源于stack exchange,提问作者Question3r
相关产品推荐
相关产品推荐

