Dependency injection with NHibernate objects
Asked Answered
I

3

8

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.

Issuant answered 4/12, 2008 at 12:41 Comment(0)
F
8

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.

Fenland answered 4/12, 2008 at 15:36 Comment(3)
Fabio (current lead programmer) explains the new constructor injection here: fabiomaulo.blogspot.com/2008/11/…Gallicanism
This is what I'm about to do, also. Can you justify using the OnLoad event instead of the Instantiate?Microcircuit
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.Fenland
H
2

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.

Hunley answered 4/12, 2008 at 14:29 Comment(3)
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.Issuant
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. ..Issuant
Along these lines, it's important to remember that, although it's convenient to use the same class for persistent entity and domain, it's not always the best solution. Especially when using an ORM, there are constraints (or requirements) put on the entity classes that make them ill-suited as great DDD domain classes. That's essentially what you're bumping into with this question, and using a service is one solution. Another might be to convert persistent entity classes to POCO domain objects to use throughout the rest of the app outside the persistence layer.Ochre
S
1

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.

Seigneury answered 4/12, 2008 at 17:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.