我目前正在处理一个项目,您可以在其中存储数据库中的产品列表。每个产品都有名称,描述......现在我要翻译产品名称,描述......
我目前的解决方案是使用转换表,我可以在其中添加所有已翻译的数据库条目,如:
product.Title= result.GetLocalized(x => x.Title, language, _localizedPropertyRepository);
和扩展方法:
public static string GetLocalized<T>(this T entity,
Expression<Func<T, string>> keySelector, LanguageDTO language, ILocalizedPropertyRepository localizedPropertyRepository)
where T : Mapping, ILocalizedEntity
{
...
resultStr = localizedPropertyRepository.GetLocalizedValue(language, entity.Id, localeKeyGroup, localeKey);
...
}
您还可以在此处看到类似的示例: https://github.com/nopSolutions/nopCommerce/blob/develop/src/Libraries/Nop.Services/Localization/LocalizationExtensions.cs
我的问题是,我对此并不满意。要使用静态类,以便我可以访问Context或在扩展方法中发送整个注入的对象看起来不是一个好习惯。还有其他方法可以解决这个问题吗?
我也使用AutoMapper,将整个实体映射到DTO。我认为当前的解决方案无法与AutoMapper一起使用。我必须做出类似的事情:
CreateMap<Product, ProductDTO>()
.ForMember(x => x.Title, opt => opt.???GetLocalized(????));
但我需要GetLocalized中的实体而不仅仅是Property。此外,我无权访问_localizedPropertyRepository或客户的语言。
答案 0 :(得分:0)
好吧,我花了一天时间,但我得到了一个有效的解决方案。因此,如果其他人遇到同样的问题,这是我的解决方案。我希望它有所帮助:
public class Mapping
{
[DataMember]
public long Id { get; set; }
}
[DataContract]
public class ProductDTO: Mapping
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string ShortDescription{ get; set; }
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Product, ProductDTO>()
.ForMember(t => t.Name, opt => opt.ResolveUsing<LocalizationResolver, EntityInfo>(src => new EntityInfo()
{
LocaleKeyGroup = "Product",
LocaleKey = "Name",
DefaultValue = src.Name
}))
.ForMember(t => t.ShortDescription, opt => opt.ResolveUsing<LocalizationResolver, EntityInfo> (src => new EntityInfo()
{
LocaleKeyGroup = "Product",
LocaleKey = "ShortDescription",
DefaultValue = src.ShortDescription
}));
}
}
public class EntityInfo
{
public string LocaleKeyGroup { get; set; }
public string LocaleKey { get; set; }
public string DefaultValue { get; set; }
}
public class LocalizationResolver : IMemberValueResolver<Mapping, object, EntityInfo, string>
{
public string Resolve(Mapping source, object destination, EntityInfo sourceMember, string destMember,
ResolutionContext context)
{
context.Items.TryGetValue("Language", out object languageObject);
context.Items.TryGetValue("Repository", out object repositoryObject);
ILocalizedPropertyRepository repository = repositoryObject as ILocalizedPropertyRepository;
LanguageDTO language = languageObject as LanguageDTO;
if (language == null || repository == null)
{
throw new ArgumentNullException($"Language and LocalizationRepository as AutoMapper Parameter");
}
if(source.Id == 0)
{
return sourceMember.DefaultValue;
}
//Get the value from the DB
return LocalizationExtension.GetLocalized(sourceMember.LocaleKey, sourceMember.LocaleKeyGroup, sourceMember.DefaultValue, source.Id, language, repository);
}
}
public static class LocalizationExtension
{
public static string GetLocalized(string localeKey, string localeKeyGroup, string defaultValue, long entityId, LanguageDTO language, ILocalizedPropertyRepository localizedPropertyRepository)
{
var resultStr = String.Empty;
if (language != null)
{
resultStr = localizedPropertyRepository.GetLocalizedValue(language, entityId, localeKeyGroup, localeKey);
}
if (string.IsNullOrEmpty(resultStr))
{
resultStr = defaultValue;
}
return resultStr;
}
public static void Localice(IMappingOperationOptions<object, object> opt, LanguageDTO language, ILocalizedPropertyRepository localizedPropertyRepository)
{
opt.Items["Language"] = language;
opt.Items["Repository"] = localizedPropertyRepository;
}
}
仍然需要优化。方法名称并不完美。 EntityInfo的创建很难看。由于依赖注入,我仍然使用整个存储库对象作为参数。此外,它尝试每次都获得一个本地化的值,这在“默认”语言中是必要的,并且会使整个内容减慢一些。