使用Mapster映射AuthenticationResult至AuthenticationResponse遇错误求助
Mapster映射不可变值对象报错的解决方法
问题场景
使用Mapster进行对象映射时,尝试将AuthenticationResult映射到AuthenticationResponse,触发以下错误:
Mapster.CompileException: Error while compiling source=FinanceManager.Domain.User.ValueObjects.UserId destination=System.Guid type=Map ---> System.InvalidOperationException: Cannot convert immutable type, please consider using 'MapWith' method to create mapping
相关代码
User类
public sealed class User : AggregateRoot<UserId> { public string FirstName { get; } public string LastName { get; } public string Email { get; } public string Password { get; } public DateTime CreatedDateTime { get; } public DateTime UpdatedDateTime { get; } private User(UserId userId, string firstName, string lastName, string email, string password) : base(userId) { FirstName = firstName; LastName = lastName; Email = email; Password = password; CreatedDateTime = DateTime.UtcNow; } }
UserId值对象
public sealed class UserId : ValueObject { public Guid Value { get; } private UserId(Guid value) { Value = value; } }
AuthenticationResult与AuthenticationResponse
public record AuthenticationResult( User User, string Token ); public record AuthenticationResponse( Guid Id, string FirstName, string LastName, string Email, string Token );
现有Mapster配置
config.NewConfig<AuthenticationResult, AuthenticationResponse>() .Map(dest => dest, src => src.User);
报错原因
UserId是不可变值对象(构造函数私有,仅暴露只读的Value属性),Mapster无法自动推断如何将其转换为Guid类型,必须手动指定映射规则。
解决方案
方案1:针对特定映射配置Id字段规则
修改现有映射配置,明确指定Id字段的来源,同时保留其他属性的自动映射:
config.NewConfig<AuthenticationResult, AuthenticationResponse>() .Map(dest => dest, src => src.User) // 自动映射FirstName/LastName/Email .Map(dest => dest.Id, src => src.User.Id.Value) // 手动指定Id的映射规则 .Map(dest => dest.Token, src => src.Token); // 映射Token字段
方案2:全局注册UserId到Guid的转换规则
如果项目中多处需要将UserId转换为Guid,可以配置全局类型映射,后续所有相关场景都会自动生效:
// 全局配置UserId转Guid config.NewConfig<UserId, Guid>() .MapWith(userId => userId.Value); // 原有映射配置可保留 config.NewConfig<AuthenticationResult, AuthenticationResponse>() .Map(dest => dest, src => src.User) .Map(dest => dest.Token, src => src.Token);
说明
- 方案1适合仅在当前映射场景需要转换的情况,针对性强
- 方案2适合全局多处需要转换的场景,减少重复配置
内容的提问来源于stack exchange,提问作者Jorge Cardoso
相关产品推荐
相关产品推荐

