Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection with NHibernate objects

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.

like image 335
Tigraine Avatar asked Dec 04 '08 12:12

Tigraine


3 Answers

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.

like image 118
Cristian Libardo Avatar answered Oct 08 '22 04:10

Cristian Libardo


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.

like image 43
Garry Shutler Avatar answered Oct 08 '22 03:10

Garry Shutler


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.

like image 1
Tim Scott Avatar answered Oct 08 '22 04:10

Tim Scott