You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Mapster代码生成中优雅注入IUserMapper至DeviceMapper?

关于Mapster代码生成中注入依赖的优雅实现方式

我正在使用Mapster及其代码生成功能,现有如下实体模型:

public class Device
{
    public Guid Id { get; set; }
    public User User { get; set; }
}

public class User
{
    public Guid Id { get; set; }
}

以及对应的Dto模型(DeviceDto, UserDto)。

随后我定义了如下Mapper接口:

[Mapper]
public interface IUserMapper
{
    UserDto MapToDto(User user);
}

[Mapper]
public interface IDeviceMapper
{
    DeviceDto MapToDto(Device device);
}

Mapster会自动生成UserMapper和DeviceMapper实现类,这部分表现很理想。但我需要将IUserMapper注入到DeviceMapper中,却找不到优雅的实现方式。目前只能通过如下方式实现:

public class MapperRegister : IRegister
{
    public void Register(TypeAdapterConfig config)
    {
        config.NewConfig<Device, DeviceDto>()
             .AfterMapping((src, dst) => { /* do nothing.*/ });
    }
}

public partial class DeviceMapper : IDeviceMapper
{
    private readonly IUserMapper _userMapper;

    public DeviceMapper(IUserMapper userMapper)
    {
        _userMapper = userMapper;
        Action1 = (src, dst) =>
                  {
                      dst.User = _userMapper.MapToDto(src.User);
                  };
    }
}

这种方式可行的原因是Mapster会生成如下代码:

public partial class DeviceMapper : IDeviceMapper
{
    private Action<Device, DeviceDto> Action1;

    public DeviceDto MapToDto(Device p1)
    {
        DeviceDto result = new DeviceDto();
 
        result.Id = p1.Id;
        Action1.Invoke(p1, result);

        return result;
    }
}

但这种方式存在明显问题:私有Action的命名非常糟糕。后续如果调整Action顺序或进行其他修改,维护会变得异常困难;当Action数量达到上百个且需要删除其中某个时,维护成本会极高。

我希望能通过如下方式实现:

public class MapperRegister : IRegister
{
    public void Register(TypeAdapterConfig config)
    {
        config.NewConfig<Device, DeviceDto>()
              .Inject<IUserMapper>("_userMapper")
              .Map(dst => dst.User, src => "_userMapper.MapToDto(src)");
    }
}

// generated
public partial class DeviceMapper : IDeviceMapper
{
    private IUserMapper _userMapper;

    public DeviceDto MapToDto(Device p1)
    {
        DeviceDto result = new DeviceDto();
 
        result.Id = p1.Id;
        result.User = _userMapper.MapToDto(p1);    

        return result;
    }
}

// manual
public partial class DeviceMapper : IDeviceMapper
{
    public DeviceMapper(IUserMapper userMapper)
    {
        _userMapper = userMapper;
    }
}

内容的提问来源于stack exchange,提问作者AnatolyBelanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 20:42:22