我需要设计一个存储部分多语言内容的应用程序;即一些域对象字段是可翻译的。 注意:我正在使用NHibernate,但这只是案例中的技术细节。
让我们考虑以下域模型:
public class Post {
public virtual int Id {get; set;}
public virtual User Author {get; set;}
public virtual string Title {get; set;} // translatable
public virtual string Content {get; set;} // translatable
}
通过互联网我发现了几种方法,其中大多数都是黑客和丑陋的;许多完全不能接受。
大多数解决方案都基于向模型引入“特殊”字段,无论是Title_FR, Content_FR, Title_EN, Content_EN
还是Dictionary<string, string> ContentTranslations
。
优点:
缺点:
后来我设计了自己的解决方案(进一步调查,恰好是重新发明轮子),它拦截了NHibernate特定的事件;即,一旦域模型的实例填充了值,则可翻译字段将使用来自抽象翻译提供者的翻译值重新填充。
优点:
缺点:
我正在寻找解决方案
(*)关于5的解释。我正在广泛使用AutoMapper的Project.To()
,以避免检索不必要的字段和SELECT N + 1问题。
我提出的解决方案不适用于投影,我相信使用投影时不会触发OnPostLoad
事件
有关该主题的任何推荐阅读?
答案 0 :(得分:1)
我不确定你的数据库结构是怎样的。如果您不想使用IDictionary(我更喜欢),那么我建议实现LocalizableString
类和相应的ICompositeUserType
,IUserType
或使用组件映射。
public class Post {
public virtual int Id {get; set;}
public virtual User Author {get; set;}
public virtual LocalizableString Title {get; set;} // translatable
public virtual LocalizableString Content {get; set;} // translatable
}
您可能还需要对linq提供程序实现一些扩展,以允许自定义查询操作。
要考虑的一些替代方法: