views:

40

answers:

2

I have a domain model type. One of its numerous properties requires an ITranslationService to provide the ability to translate its return value into the appropriate language.

Should I inject the ITranslationService into the constructor of the domain model type (thereby having to alter everywhere the type is instantiated and having to be concerned about initialisation when retrieved via NhIbernate), even though it is used by a tiny part of the type (one of many properties); or is there another functional pattern I can use?

Does anyone have any relevant experience they can share?

+2  A: 

I would not expect the domain object to do the translation - instead, use the translation service with the domain object (or the relevant property value) as a parameter, and return the translated value. For example, you could simply do

var translatedString = yourServiceInstance.Translate(theDomainObject.Property);
Tomas Lycken
+1 This is better. The other design sounds like a violation of the SRP.
Mark Seemann
My understanding of your answer is that you're moving the dependency on the translationservice to the client of the method? Your code looks exactly like the code in the property as-is. My problem is supplying the dependency. One possibility might be to inject the translationservice into a new accessor method. Is it straightforward to expose accessor/mutator method pairs as nhibernate properties? ...I feel out of my depth
Ben Aston
@Ben: Yes, move the dependency to the object that's using the domain object, rather than having it in the object itself. I'd imagine the above code to be in a controller action, or a view, if this was an ASP.NET MVC web application. The goal with this is to make your domain objects just hold data, while someone else is responsible for processing that data.
Tomas Lycken
@Tomas - I understand what you are saying. There is a tension though with trying to avoid an anemic model.
Ben Aston
Is translation required by the domain entity to perform its purpose, or is it a user interface concern?Anaemic domain models are entities which expose all their internal state for modification and lack domain specific behaviour. An entity need not, and in my opinion should not, utilise injected services in order to provide behaviour.
mattk
Translation is required by the domain entity to perform its function. If injection of a service is to be avoided, where should the translation be performed? In another service?
Ben Aston
+1  A: 

Should I inject the ITranslationService into the constructor of the domain model type

Yes, that may make sense, depending on your situation. If you would always avoid the injection of services into entities, then that might lead to an anemic domain model which is an anti-pattern.

Code which needs to instantiate entities can be shielded from the extra constructor argument by using a factory, which takes care of the dependency injection.

NHibernate can also inject services into an entity via the constructor: http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html

Wim Coenen
Thanks. In the end I removed the dependency cf Tomas, but I liked your factory discussion.
Ben Aston