Posted by Siim on November 19th, 2009
There has been some discussion over the topic already and there are different opinions. I have been using Repository model all the way so far. I have implemented generic base repository for all common operations and when there are some specific needs (view specific query for example!) for some types then I’ll create specific repository. I know that repositories should be created only for aggregate roots but there I have encountered a little problem. View needs to display data from different entities (aggregates or not) so I cannot always follow the principle of repository per aggregate root. So this poses a problem here – repositories are cluttered with view specific needs. And moreover – repository methods are decorated with sorting and paging parameters which definitely shouldn’t be there. So I decided to change that.
There have been some discussion about using multiple models of the domain for different purposes. For example different kind of a model for reporting purposes. It can even be different kind of data store for that model. Udi and Ayende (didn’t find exact posts anymore) have blogged about that before. Complex views with special needs can be also considered as a way of reporting. In my case, using wholly different model for a view is kind of a overkill so I try to leverage the problem by using query objects separated from the repository. They don’t use repositories by themselves so query objects can be viewed as "specific repositories for views" and they live only in presentation layer. And they don’t operate with domain objects, only with view specific objects like DTOs, filtering specifications. By using this kind of approach, writing complex view specific queries should be pretty easy. I’m not tied to NHibernate criteria, I can use HQL or even ADO.NET. Currently I’m using HQL which returns directly DTOs but I’m thinking of giving a try to LINQ for NHibernate.
When using repositories, I used Expressions to represent sorting and filtering specification. But this seems now overly complex when considering that there were some heavy mappings from string format to Expression format. So now, when it’s only a presentation concern, I can use plain strings, just like they come from the view and do the proper mappings in the query object itself. Like they say – KISS.
Posted by Siim on October 29th, 2009
There are not so many business applications which need multilingual content. I exclude any kind of CMS’s, they aren’t “true” business application anyway, in my opinion. But the current project I’m working on has that kind of requirement – most of the data must be available in multiple languages and users should easily and intuitively browse and edit that data in current working language. Part of this requirement is not so easy to achieve. Especially when there is a constraint that there cannot be a default language in it’s standard term – object may be available in any language and even only in that language.
Currently we are using a single translations table where translation is identified by it’s context which is mostly some sort of object/field key or basically can be any string. All the translatable fields are stored in the entity table also as a “original value”. This solution is far from perfect and do not fit very well into domain model in general. It was meant to be a quick draft of the solution.
Usually, this kind of translation should be invisible in domain model perspective. But in my case I think it should be reflected in domain model also, because it IS one of the purpose and requirement of the business application. There are two possible viewpoints to consider – a technical perspective and a user’s point of view. I’ve explored different models that people have used before and I think that the solution that Davy Brion describes seems the best one.
It is tied to the domain object. That means there are direct relation between entity and it’s translations. It simplifies CRUD operations on it, NHibernate can take care of it itself. Searching from localized versions are also quite simple, performance overhead is minimal.
It uses a single translations table. Actually there are couple of tables, but all translations are stored and accessed from one place. This makes later maintenance simpler and don’t create so much noise in the domain model (and in data model also).
It’s quite simple to extend and it fits perfectly into NHibernate. I find that for my solution I should also apply the default language attribute on the translation, because for different object, the term default language can mean different language from what is global default languages, if such exists.
When using this model, every translatable property (a product’s name for example) is an object which holds at least one localization. We don’t have a term original like I have seen in some models, every value is a localization. This makes things simpler in users point of view.
I don’t write about any technical data, you can check that on Davy’s blog, but I will update this blog post when I do any changes to this model. And I’ll try to provide some samples then.