如何在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
相关产品推荐
相关产品推荐

