Automapper Mapping for Localization Resolver in a

2019-06-06 17:12发布

问题:

I found a way to use Automapper for Language mapping based on the active Culture.

The question is if it's possible to build a generic Resolver to map all the models that use the Resolver.

In this Case, the models to map have always the same properties, Id and Name (including the language properties Name_PT, Name_FR and Name_EN):

// MODELS

public class MakeDto
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
    public string Name_PT { get; set; }
    public string Name_FR { get; set; }
    public string Name_EN { get; set; }
}

public class MakeViewModel
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ModelDto
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
    public string Name_PT { get; set; }
    public string Name_FR { get; set; }
    public string Name_EN { get; set; }
}

public class ModelViewModel
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
}

public class FuelDto
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
    public string Name_PT { get; set; }
    public string Name_FR { get; set; }
    public string Name_EN { get; set; }
}

public class FuelViewModel
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
}

// AUTOMAPPER PROFILE

public class DtoToViewModelMappingProfile : Profile
{
    public override string ProfileName
    {
        get { return "DtoToViewModelMappings"; }
    }

    protected override void Configure()
    {
        CreateMaps();
    }

    private static void CreateMaps()
    {
        Mapper.CreateMap<ModelDto, ModelViewModel>();
        Mapper.CreateMap<MakeDto, MakeViewModel>()
            .ForMember(dest => dest.Name, opt => opt.ResolveUsing<CultureResolver>());
        Mapper.CreateMap<FuelDto, FuelViewModel>();
    }

    public class CultureResolver : ValueResolver<MakeDto, string>
    {
        protected override string ResolveCore(MakeDto makeDto)
        {
            switch(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName.ToUpperInvariant())
            {
                case "FR":
                    return makeDto.Name_FR;
                case "EN":
                    return makeDto.Name_EN;
            }
            return makeDto.Name_PT;
        }   
    }
}

Thanks.

回答1:

You can extract an interface like below:

public interface ILocalizable
{
    string Name { get; set; }
    string Name_PT { get; set; }
    string Name_FR { get; set; }
    string Name_EN { get; set; }
}

public class FuelDto : ILocalizable
{
    // Primary properties
    public int Id { get; set; }
    public string Name { get; set; }
    public string Name_PT { get; set; }
    public string Name_FR { get; set; }
    public string Name_EN { get; set; }
}

Then tune your resolver like below:

public class CultureResolver : ValueResolver<ILocalizable, string>
{
    protected override string ResolveCore(ILocalizable dto)
    {
        switch(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName.ToUpperInvariant())
        {
            case "FR":
                return dto.Name_FR;
            case "EN":
                return dto.Name_EN;
        }
        return dto.Name_PT;
    }   
}