migajek
migajek

Reputation: 8614

Querying-friendly domain objects localization

I need to design an application which stores partially multi-lingual content; i.e. some of the domain objects fields are translatable. note: I'm using NHibernate, but this is just a technical detail in the case.

Let's consider the following domain model:

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
}

Looking through the internet I've found several approaches, most of them hackish and ugly; many completely unacceptable. Most of the solutions are based on introducing "special" fields to the model, whether it's like Title_FR, Content_FR, Title_EN, Content_EN or Dictionary<string, string> ContentTranslations.

Pros:

Cons:

Later on I've designed my own solution (which, further investigating, happened to be reinventing the wheel) which intercepts the NHibernate-specific events; i.e. once the instance of domain model is populated with values, the translatable fields are re-populated with translated values from abstract translation provider.

Pros:

Cons:

I'm looking for the solution which

  1. integrates possibly seamlessly. No special fields introduced to the domain model
  2. Applies translations automatically
  3. Takes care not to overwrite original values when updating the (translated) domain object
  4. is querying friendly; i.e. the introduction of the mechanism doesn't require the LINQ queries to be changed significantly. This probably disqualifies "joinable" translation table
  5. ideally, the solution should not break the LINQ projection; this however is probably just asking way too much ( * )

( * ) word of explanation on 5. I'm using AutoMapper's Project.To() extensively, to avoid retrieving unnecessary fields and SELECT N+1 problems. The solution I've came up doesn't work with projection, I believe OnPostLoad event is not fired when using projection

Any recommended reading on the subject?

Upvotes: 1

Views: 112

Answers (1)

hazzik
hazzik

Reputation: 13344

I'm not sure how your DB structure looks like. If you do not want to use IDictionary (which I would prefer), then I would propose implementing a LocalizableString class and a corresponding ICompositeUserType, IUserType or using Component mapping.

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
}

You will probably also need to implement some extensions to the linq provider, to allow custom query operations.


Some alternative approaches to consider:

  • using formula columns formula columns for localized fields
  • using my very own DelegateDecompiler to allow queries of the calculated properties.

Upvotes: 1

Related Questions