views:

1147

answers:

3

I am wondering how to tell NHibernate to resolve dependencies on my POCO domain objects.

I figured out that methods like CalculateOrderTax should be in the Domain object because they encode domain specific business rules. But once I have two of those I am violating SRP.

It would be no problem to extract those methods to Strategy classes, but I wonder how to make NHibernate load those.

It doesn't seem like a good solution to loop through a list of objects in the repository to do get/set based Dependecy injection before handing the object off to the higher layers.

I am also using Castle Windsor for my Depency injection right now.

+1  A: 

As no-one seems to be able to answer your question at the moment I thought I'd suggest restructuring your code to remove the need for the Order to calculate it's own tax.

You could delegate it to a OrderTaxService which takes an Order object and returns an OrderValue object or something along those lines.

This will keep the logic in your domain but remove the need to attach it to your Order objects.

Garry Shutler
That's how I do it right now. I pass the order around all the time and let external classes calculate stuff. It just feels wrong because my objects are a) mutable and b) I need to carry around those Services all the time because if I don't want to new them up from business logic code.
Tigraine
It gets trickier when there are multiple strategies for one thing. Like Orders with normalTaxrate get calculated differently than others. I then have to let the Services decide how to calculate taxes for a given domain object. ..
Tigraine
+4  A: 

I've been using interceptors for similar tasks:

An interceptor that modifies loaded entities:

public class MyInterceptor : EmptyInterceptor
{
    public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types)
    {
        return InjectDependencies(entity as MyEntity);
    }
}

Associate it with a session:

nhSessionFactory.OpenSession(myInterceptor);

I've also read somewhere that there would be better support for custom constructor injection in the upcoming 2.1 release but I can't seem to find the reference right now.

Cristian Libardo
Fabio (current lead programmer) explains the new constructor injection here: http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html
Mauricio Scheffer
This is what I'm about to do, also. Can you justify using the OnLoad event instead of the Instantiate?
Bruno Lopes
It seems Instantiate is a way to make your own factory (which could be quite nice if you want to use constructor injection). I just needed inject a service into an overridable base class.
Cristian Libardo
+1  A: 

I agree with Garry that you should remove service dependencies from your domain objects as much as possible. Sometimes it makes sense, such as encryption/decryption. In that case you can hide it in the infrastructure using interception or IUserType. I think the latter is favorable when you can use it. This article shows in detail how to do it. I am doing this and it works quite fine.

Tim Scott