从外部将值传递给AutoMapper类型转换器 [英] passing around values to an AutoMapper Type Converter from outside

查看:141
本文介绍了从外部将值传递给AutoMapper类型转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多语言数据库,该数据库基于键和枚举Language返回值.当我将数据库对象转换为模型时,我希望模型包含基于键和当前语言的转换后的值.

I have a multilingual database, which returns values based on a key and an enum Language. When I convert a DB object to a model, I want the model to contain the translated value based on the key and the current language.

键来自DB对象,但是如何将当前语言传递给Mapper.Map()函数?

The key comes from the DB object but how can I pass the current language to the the Mapper.Map() function?

当前,我正在使用[ThreadStatic]属性在调用Mapper.Map<>之前设置区域性,并在TypeConverter中进行检索.

Currently, I am using a [ThreadStatic] attribute to set the culture before calling Mapper.Map<>, and to retrieve it in the TypeConverter.

public enum Language
{
    English, French, Italian, Maltese
}

public class MultilingualValue<T>
{
    public Dictionary<Language, T> Value { get; set; }
    public MultilingualValue()
    {
        this.Value = new Dictionary<Language, T>();
    }
}

public class PersonData
{
    public string FirstName { get; set; }
    public MultilingualValue<string> City { get; set; }
}

public void MapPerson()
{
    PersonData personData = new PersonData();
    personData.FirstName = "John";
    personData.City = new MultilingualValue<string>();
    personData.City.Value[ Language.English] = "The Zurrieq";
    personData.City.Value[Language.French] = "Le Zurrieque";

    MultilingualValueData.CurrentLanguage = Language.English; 

    var personModel = Mapper.Map<PersonData, PersonModel>(personData);
}

public class MultilingualValueToBasicDataTypeConverter<T> : ITypeConverter<MultilingualValue<T>, T> 
{
    public T Convert(ResolutionContext context)
    {
        var currentLanguage = MultilingualValueData.CurrentLanguage; //THIS IS THE [ThreadStatic] VARIABLE
        if (currentLanguage == null) throw new InvalidOperationException("Please make sure to fill in CurrentLanguage");

        MultilingualValue<T> sourceMultilingualValue = (MultilingualValue < T > )context.SourceValue;

        T destinationValue = default(T);
        if (sourceMultilingualValue != null)
        {
            destinationValue = sourceMultilingualValue.Value[currentLanguage.Value];
        }

        return destinationValue;
    }
}        

public static class MultilingualValueData
{
    [ThreadStatic]
    public static Language? CurrentLanguage;
}

我省略了配置,因为我认为它们对于此示例不是必需的.如果您需要它们,我也将其发布.

I left out the configurations as I think they're unneccessary for this example. If you need them, I'll post them as well.

虽然可行,但我发现此解决方法非常难看.有什么方法可以通过ResolutionContext传递数据?

While this works, I find this workaround quite ugly. Is there any way to pass data through the ResolutionContext?

推荐答案

只需使用需要Action<IMappingOperationOptions>Map重载.您可以将配置元素添加到Items属性,然后将其传递到您的ITypeConverter

Just use the Map overload that takes a Action<IMappingOperationOptions>. You can add configuration elements to the Items property that are then passed to your ITypeConverter

public class CustomConverter : ITypeConverter<string, string>
{
    public string Convert(ResolutionContext context)
    {
        return "translated in " + context.Options.Items["language"];
    }
}

internal class Program
{
    private static void Main(string[] args)
    {
        AutoMapper.Mapper.CreateMap<string, string>().ConvertUsing<CustomConverter>();
        var result = AutoMapper.Mapper.Map<string, string>("value" , opt => opt.Items["language"] = "english");
        Console.Write(result); // prints "translated in english"
        Console.ReadLine();
    }
}

这篇关于从外部将值传递给AutoMapper类型转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆