キーと列挙型Language
に基づいて値を返す多言語データベースがあります。 DBオブジェクトをモデルに変換するとき、キーと現在の言語に基づいて変換された値をモデルに含める必要があります。
キーはDBオブジェクトから取得されますが、現在の言語をMapper.Map()
関数に渡すにはどうすればよいですか?
現在、私は[ThreadStatic]
属性を使用して、Mapper.Map<>
を呼び出す前にカルチャを設定し、それを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;
}
この例では不要だと思うので、構成を省略しました。あなたがそれらを必要とするならば、私もそれらを投稿します。
これは機能しますが、この回避策はかなり醜いです。 ResolutionContext
を介してデータを渡す方法はありますか?
Action<IMappingOperationOptions>
をとるMap
オーバーロードを使用するだけです。構成要素をItems
プロパティに追加して、それを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();
}
}