简体   繁体   中英

How can I pass parameters to an AutoMapper Profile in ABP?

I need to customize the way MyAutoMapper profile maps my objects to DTOs. From one of my ApplicationServices, I use an ObjectMapper for a relatively simple mapping. The catch is that ABP's AutoMapper isn't the normal AutoMapper that everyone knows about.

Below is a snippet of what it would ideally look like; Except opt.MapFrom(m => Localizer[m.Type.ToString()]) and _objectMapper.Map<Preparation, DtoPreparation>(preparation, _localizer) cannot work that way.

public class MyAutoMapperProfile : Profile
{
    public MyAutoMapperProfile()
    {
        CreateMap<Preparation, DtoPreparation>()
            .ForMember(m => m.PreparatorType, opt => opt.MapFrom(m => m.Type))
            .ForMember(m => m.PreparatorTypeString, opt => opt.MapFrom(m => Localizer[m.Type.ToString()]));
    }
}

public class SlipsAppService : TaxesAppService
{
    private readonly IObjectMapper<TaxesApplicationModule> _objectMapper;
    private readonly ISlipsManager _slipsManager;
    private readonly IStringLocalizer<TaxesResource> _localizer;

    public SlipsAppService(ISlipsManager iSlipsManager, IObjectMapper<TaxesApplicationModule> objectMapper, IStringLocalizer<TaxesResource> localizer)
    {
        _objectMapper = objectMapper;
        _slipsManager = iSlipsManager;
        _localizer = localizer;
    }

    [Microsoft.AspNetCore.Mvc.HttpPost("/api/slips/get-or-create-preparation")]
    public async Task<DtoPreparation> GetOrCreateCurrentPreparation(BaseGetterInput input)
    {
        var preparation = await _slipsManager.GetOrCreatePreparation(input.Id);
        return _objectMapper.Map<Preparation, DtoPreparation>(preparation, _localizer);
    }
}

I can't find a way to pass any information from my ApplicationService to the AutoMapper Profile, as IObjectMapper.Map<>() has no parameters for additional options or objects, unlike the normal AutoMapper.

Maybe there is a way to register the Profile in dependency injection, but with my limited knowledge of the framework, I couldn't find a clue...

For now, my problem is only with Localization, but really it can apply to anything. Since my DTOs contain other nested DTOs, managing extra stuff outside of the AutoMapper isn't an option, unless I change the structure of my application just for a workaround.

Since you are using one mapping profile per appservice, here is a good suggestion that works for me:

  • Create a class the implements the IMappingAction interface.
  • In the implementation of the Process method, inject your ILocalizer and use it with the source and destination.
  • In your mapping, instead of passing the localizer, chain call with AfterMap.

Here is an example:


public class MyAutoMapperProfile : Profile
{
    public MyAutoMapperProfile()
    {
        CreateMap<Preparation, DtoPreparation>()
            .ForMember(m => m.PreparatorType, opt => opt.MapFrom(m => m.Type))
            .AfterMap<PreparationDtoLocalizerAction>;
    }
}

public class PreparationDtoLocalizerAction : IMappingAction<Preparation, DtoPreparation>
{
    private readonly IStringLocalizer<TaxesResource> _localizer;

    public PreparationDtoLocalizerAction(IStringLocalizer<TaxesResource> localizer)
    {
        _localizer = localizer;
    }

    public void Process(Preparation source, DtoPreparation destination)
    {
        destination.PreparatorTypeString = _localizer[source.Type.ToString()]
    }
}

public class SlipsAppService : TaxesAppService
{
    private readonly IObjectMapper<TaxesApplicationModule> _objectMapper;
    private readonly ISlipsManager _slipsManager;

    public SlipsAppService(ISlipsManager iSlipsManager, IObjectMapper<TaxesApplicationModule> objectMapper)
    {
        _objectMapper = objectMapper;
        _slipsManager = iSlipsManager;
    }

    [Microsoft.AspNetCore.Mvc.HttpPost("/api/slips/get-or-create-preparation")]
    public async Task<DtoPreparation> GetOrCreateCurrentPreparation(BaseGetterInput input)
    {
        var preparation = await _slipsManager.GetOrCreatePreparation(input.Id);
        return _objectMapper.Map<Preparation, DtoPreparation>(preparation);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM