AnatolyBelanov
AnatolyBelanov

Reputation: 62

Mapster injection

I use mapster and its code generation. I have models like this:

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

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

And the same models for Dto (DeviceDto, UserDto).

Then I make the interfaces:

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

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

Mapster will generate UserMapper and DeviceMapper - that's great. I need to inject IUserMapper into DeviceMapper. And here is the problem. I can't find the way to do it well. All that I can do is this:

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);
                  };
    }
}

This is possible because mapster generates

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;
    }
}

Of course, it does solve my problem. But naming of private actions is terrible. If after some time I will change order of my actions, or something else - it would be a nightmare. If quantity of actions would be 100+ and i would need to delete one of them I will suffer.

Is it possible to do something like

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;
    }
}

Upvotes: 1

Views: 300

Answers (0)

Related Questions