问题描述
我有一个多语言数据库,该数据库基于键和枚举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类型转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!