Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at
Inject DI Container into Domain Objects with NHibernate

I've been asked a couple of times how to give a domain object access to a dependency injection (DI) container, such as Castle Windsor, if the domain object is loaded via an ORM, such as NHibernate.  There are two apparent ways to do this:  1) you can manually give the domain object access to the DI via "setter injection" from your controller or service layer, or 2) you can use an NHibernate IInterceptor to preset the DI container when the object is loaded from the database.  The latter is much cleaner and avoids having to pass service object references through middlemen classes.

Disclaimer:  I feel I should add a disclaimer to this post that this technique should not be used as standard practice.  Giving domain objects direct access to the DI container can be very powerful but also enables the domain layer to take on responsibilities that it should not have.  Furthermore, having access to the DI container from the domain layer creates, at the very least, a virtual dependency on everything available via the DI container; consequently, additional maintenance issues may have to be considered.  Finally, the DI container itself presents another layer of indirection which can be difficult to easily understand during the maintenance phase of a project.  With that said...

Assume you want to show who a customer was referred by but can't set it up in a nice HBM mapping.  The only way you can do it, for some reason or another, is by having the Customer instance make an explicit call to the database.  Our goals are 1) to keep Customer only dependent on DAO interfaces and 2) to automatically inject the DAO dependency to Customer as soon as its loaded from the database even if it's loaded via an ORM.  (Obviously, this example is a little strange to begin with but illustrates the technique, nonetheless.  The technique is equally applicable for providing other services, such as an email utility.)

If you'd like to walk through modifying an application, already wired for Castle Windsor, to accommodate doing this, download the "enterprise" sample app found within the MVP with ASP.NET article on and follow the steps below.  (Alternatively, you can just download the sample at the end of this post to see the finished product.)  You'll need to follow the steps found within the article to get it working with your SQL Server/Northwind database.  The modification steps to the sample app are as follows:

1) First, since we always take a test-driven approach (right?), amend MvpSample.Tests.Data.CustomerDaoTests to reflect the following:


[Category("NHibernate Tests")]

public class CustomerDaoTests


    /// <summary>

    /// Initializes the NHibernate session bound to

    /// HttpContext. This TestFixtureSetUp could be

    /// moved to a NHibernateUnitTest class so you

    /// don't have to

    /// copy/past it into every unit test class.

    /// </summary>


    public void Setup() {



            new NHibernateInterceptor());






    /// <summary>

    /// Tests successful dependency injection

    /// from within the domain layer.

    /// </summary>


    public void TestGetReferrer() {

        IDaoFactory daoFactory =

            new NHibernateDaoFactory();

        ICustomerDao customerDao =



        Customer foundCustomer =

            customerDao.GetById("CHOPS", false);

        Customer referrer =



        Assert.AreEqual("Folies gourmandes",



... remainder of pre-existing tests...

In the above code, you can see that we're doing two new things.  First, we've added the call to RegisterInterceptor to the Setup method.  (Since you have to register interceptors before starting a transaction, the order is important here.)  So, as the code implies, we can wire up container DI via a custom, NHibernate Interceptor.  The second thing to note is the new test.  We'll be adding the method GetReferrer, which will use the DI container, to the Customer class.

2) If you try to compile the above change, VS will initially complain about the missing NHibernate interceptor class.  So add a new class called NHibernateInterceptor and at it to the MvpSample.Data package.  Since it's specific to the data layer - and to NHibernate for that matter - the data layer is the appropriate place to put it.  The class is defined as follows:

namespace MvpSample.Data


    public class NHibernateInterceptor : IInterceptor


        public bool OnLoad(object entity, object id,

            object[] state, string[] propertyNames,

            IType[] types)


            // Only use "setter injection" to give objects

            // that implement IUsesDependencyInjection a

            // reference to the DI container.

            if (typeof(IUsesDependencyInjection)

                .IsInstanceOfType(entity)) {

                ((IUsesDependencyInjection) entity)

                    .DependencyInjectionContainer =

                    new WindsorContainer(new XmlInterpreter());



            // Even though we gave the object it's DI

            // container, return the fact that we

            // didn't modify the persistent properties

            return false;



        public bool OnFlushDirty(object entity,

            object id, object[] currentState,

            object[] previousState, string[] propertyNames,

            IType[] types)


            // Return the fact that we didn't

            // modify the entity

            return false;



        public bool OnSave(object entity, object id,

            object[] state, string[] propertyNames,

            IType[] types)


            // Return the fact that we didn't

            // modify the entity

            return false;



        public void OnDelete(object entity, object id,

            object[] state, string[] propertyNames,

            IType[] types) {}



        public void PreFlush(ICollection entities) {}


        public void PostFlush(ICollection entities) {}


        public object IsUnsaved(object entity) {

            return null;



        public int[] FindDirty(object entity, object id,

            object[] currentState, object[] previousState,

            string[] propertyNames, IType[] types) {

            return null;



        public object Instantiate(Type type, object id) {

            return null;




The only bit of interesting code is found within the method OnLoad.  This method first checks to see if the persistent object being loaded implements the interface IUsesDependencyInjection and then sets the publicly accessible property to give the object a reference to the Castle Windsor container.  This is also called "setter injection."

3) The next logical step is to define the IUsesDependencyInjection interface.  This will be implemented by our persistent business objects which should have a reference to the DI container when they're loaded from the database.  The interface will be added to the MvpSample.Core project since the business objects will be implementing it.  The simple interface is as follows:

namespace MvpSample.Core.DataInterfaces


    public interface IUsesDependencyInjection


        IWindsorContainer DependencyInjectionContainer {






4) Now modify MvpSample.Core.Domain.Customer to implement this interface.  It'll immediatly complain that Custom needs to implement the getter/setter from the interface.  You have a choice here; you can either implement the code in the Customer class itself, or, you can add it to the persistent object super class called DomainObject.  (I.e. All persistent objects inherit from this class in the sample project.)  I chose to put the implementation details into DomainObject for two reasons:  A) it's now reusable without any duplicated code and exposes a very handy public setter for all persistent classes and B) you can place pre-condition code in the getter to ensure that the DI container has been set before it's used.  The latter point will avoid any unexpected "object reference was null" exceptions.  The downside to putting it into DomainObject is that it exposes a lot more power to a lot more classes.  So this should be avoided if it's only going to be used by a couple of objects.  (Regardless, DomainObject shouldn't inherit from IUsesDependencyInjection, only Customer should, at this time; otherwise, the interceptor will automatically give every persistent object a reference to the container...which might not be a terrible thing in some situations.)  So in the DomainObject class, we add:

/// <summary>

/// Publicly accessible to allow the dependency

/// injection container to be given to the object. 

/// If you have your domain object implement

/// <see cref="IUsesDependencyInjection" />,

/// it'll automatically be wired up with the DI

/// container when loaded with the ORM. If

/// someone  has switched out the ORM or

/// disabled this, then the container can still

/// be set via this property.

/// </summary>

public IWindsorContainer DependencyInjectionContainer {

    set {

        dependencyInjectionContainer = value;


    get {

        if (dependencyInjectionContainer == null)

            throw new ApplicationException(

                "dependencyInjectionContainer has not " +

                "yet been initialized");


        return dependencyInjectionContainer;



5) The only remaining piece, to get the unit test working, is to add the GetReferrer method to Customer:

/// <summary>

/// This is an example of using DI from

/// the domain layer itself.

/// </summary>

public Customer GetReferrer() {

    // Obviously, hard-coding "FOLIG" is

    // unrealistic...but it'll work to illustrate

    // the use of a DI container from within the

    // domain layer.

    return ((IDaoFactory)


        .GetCustomerDao().GetById("FOLIG", false);


6) The NUnit test that we wrote previously should now compile and run successfully.  (Be sure to copy the web's Config folder into the MvpSample.Tests/bin/Debug so the unit test will find it.  A post-compilation script would be good for doing this on future builds.)

7) Now that we have the unit test working successfully, all we have to do is modify the NHibernateSessionModule (an IHttpModule) to register the interceptor when the transaction-per-web-request is started:

/// <summary>

/// Opens a session within a transaction at the

/// beginning of the HTTP request. This doesn't

/// actually open a connection to the database

/// until needed.

/// </summary>

private void BeginTransaction(object sender, EventArgs e) {

    // This needs to be called BEFORE begin

    // transaction since an interceptor can't

    // be registered after a session has been

    // created.


        .RegisterInterceptor(new NHibernateInterceptor());





Obviously, you don't have to use a transaction for this to work, but it shows how an interceptor works when a transaction is being used.

8) To see it all in action, add a lblReferredBy label to the web project page found at /Views/EditCustomerView.ascx and set its text value to the referrer from within the set property of CustomerToUpdate, found within its code-behind page:

public Customer CustomerToUpdate {

    get { ... }

    set {


        lblReferredBy.Text =





That's it in a nutshell.  The process goes as follows:

  1. Web request gets sent to server.
  2. NHibernateSessionModule creates the interceptor, registers it with the Open-Session-in-View session and begins a transaction.
  3. Page loads a persistent object from the database.
  4. NHibernateInterceptor checks to see if the object being loaded implements IUsesDependencyInjection and sets its DI container, accordingly.
  5. Other code calls the method GetReferrer, found on the Customer object.  GetReferrer uses the DI container to load another Customer from the database via a data-access object.  But before it's loaded, the getter method of the DI container ensures that the DI container is available for use and throws an exception if not. 

This tutorial has shown how to give a domain object a reference to a DI container if that object was loaded from the database using NHibernate.  The attached sample is a working version of all the steps mentioned above.

As always, please let me know if you have any comments, questions or suggestions.


Posted 02-05-2007 5:52 PM by Billy McCafferty
Filed under: , ,



Andrew wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-06-2007 3:08 AM

Good approach, Billy. Thank you very much. BTW, there is also an article on CodeProject, that refers same problem.

I also thought about IInterceptor, but was going to use Instantiate method. In the Instantiate, i could delegate creation (and resolving all dependencies) of my DomainObject to Windsor. But this approach would require to register all domain objects in Windsor as well.

Martijn Boland wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-06-2007 12:20 PM

I don't know if this approach is right. Having a reference to the DI container in a Domain object just feels very strange. How would you unit-test this? By mocking the container?

Rob Eisenberg wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-06-2007 12:22 PM

Great post!  I came across another interesting post a few days ago that deals with the same type of problem, but as it relates DI with WCF services.

Colin Place wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-06-2007 1:15 PM

I agree with Martijn on this.  Isn't the whole point of a DI container to manage the dependencies between your domain objects and services?  This approach implies you're using the DI container as a service locator as opposed to true dependency injection.


Billy McCafferty wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-06-2007 7:06 PM

Martijn, Colin,

I agree with both of you.  Honestly, I've never used this approach in a production environment for the very reasons that you've stated.  On the other hand, I believe it presents true value in a few situations.  As a rule of thumb, I don't think the domain model should have access to the DaoFactory, or especially to the DI container.  The main problem is that it allows any POCO to meddle in business they shouldn't be in.  Essentially, this extends a domain model's reach of responsibility and forces you to consider further maintenance issues.  If used sparingly, it's a very powerful technique...but I would agree that it should be avoided in most situations.

Henrik wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-07-2007 5:34 AM

Hi Billy,

I have a couple of questions... First of all: the open-session-in-view pattern, with a transaction starting every request; exactly how performant is that? Doesn't that start the database transaction at the same time; and if you're only reading from the database; why use a transaction?

Then I was wondering about how you pose complex queries in the article about nhibernate best practices, that you have at codeproject: there is HQL which very useful for this purpose, and what I do when I must pose an advanced query, is to extend the IObjectDao interfacem with the methods whose results I'm after, by implementing the methods, concretely inside the <code> ObjectNHibernateDao : GenericNHibernateDao<MyObject, IObjectDao</code>

Looking at DDD, at least what I've read of it; what you call DAOs are the same as what is called object repositories. "the Repository acts as a storage place for globally accessible objects." The "DDD Quickly" :p -book I've downloaded from InfoQ suggests that you can pass object via the Strategy pattern to the constructor of these repositories; something your NHibernate inheritance model has solved via the daoFactory and the dependency injection the Castle project gives us.

However, the book also suggests that the repository, or in this case the data access objects, may locally cache the retrieved objects. From what I can gather on the NHibernate cache functions, NHibernate uses first-level cache on a per-transaction basis, i.e. session-basis, but the second-level cache is configurable, so it could be used. It seems like it only works with "get by id" and not when using "complex" hql -- is this also your experience? Then, if you use second-level cache, perhaps it wouldn't be a good idea to cache the more complex queries in the repositories?

Also, there are services... Citing the book:

"There are three characteristics of a Service:

1. The operation performed by the Service refers to a domain

concept which does not naturally belong to an Entity or Value


2. The operation performed refers to other objects in the domain.

3. The operation is stateless."

So for example, if you'd want to get all customers with referrers and transform them to xml and then mail them to all subscribers via a computer you access via remoting, services would be a good choice :P. Are you using services in that manner? Do your projects have one more assembly, that might be named "application layer" in which you can put services and other logic? And what if you don't require much logic, it seems like you just bypass anything like an application layer and simply load the domain objects directly in the presentation layer; be it in a gridview or otherwise. Ever thought of using value objects (aka. data transfer objects)?


Matt wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-07-2007 5:06 PM


Great Article, One question, where you are using the presenter and the view (ascx) page you have an aspx for each view, would this pattern work for instance I had one Customers.aspx and used panels within the customer page to display the views, or is the pattern dependant on having an aspx per view. What would be the best approach for achieveing a single aspx for multiple views?

Billy McCafferty wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-09-2007 10:15 AM


An article was published a while back on MSDN which describes using the MVP pattern with a service layer:  In my current work, I use Castle Windsor to act as a sort of service layer which provides the service dependencies to the presenters layer.

To answer your other question, using value objects / DTOs are a great technique for simplifying the communications between a presenter and a view.  For instance, suppose you have an object with 12 properties which is being edited within a view.  Furthermore, you may only need 3 of the properties to be available for editing.  In this case, it probably makes sense to pass the data between the view/presenter layers as primitives or within a DTO.  In this way, you've separated the unnecessary bits which the view need-not, and probably should-not, have access to.


Billy McCafferty wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-09-2007 10:33 AM


Great question.  I had a situation in my current project wherein I wanted to have a comment-management tool which could be slapped into various pages.  The "top-level" ASCX, ManageComments, then turned on/off various panels to list/add/edit comments.  In this way, I could slap a multi-pieced user-control into an ASPX page.  To be applicable to your question, you could envision my ManageComments ASCX as being equivalent to the ASPX page you're talking about.

Deciding how many pieces of functionality should be included in a single page and coordinated via panels really comes down to how much maintenance overhead will the technique incur.  The nice thing about having one ASPX/ASCX relationship is that it's easy to maintain.  A serious drawback is that it creates a LOT of ASPX/ASCX pages which can be hard to wade through if they're not named descriptively.

In hindsight, I'd only highly recommend the ASPX/ASCX page if there's a possibility that the ASPX page will host multiple controls, such as a web parts manager page.  Otherwise, it probably makes sense to bypass using ASPX as a view initializer and have the ASPX be the view itself.  This was a good lessoned learned on my current project.  On the flipside, keeping one-ASCX-per-view has made it very easy to move views around to different pages and to slap multiple views into the same ASPX.

What I would recommend is developing a couple of simple approaches of your ideas and discuss with the rest of the team which seems more natural and appropriate for everyone.  Additionally, it may make sense to have a single ASPX/ASCX coordinate a multitude of views within an application if the views are closely related.

In all honesty, I think MVP in some sort of implementation is the single best way to separate code from ASP.NET pages if you're not using a third party framework.  With that said, I'm starting to notice maintenance problems with the entire ASP.NET approach to managing the page lifecycle and look forward to using Castle MonoRail or Maverick .NET on my next project.  I just haven't been able to find a way to wrangle the ASP.NET lifecyce model and still think to myself that I have a very clean design throughout the entire lifetime of the project.  For some purposes, it's a great benefit; in others, it just adds a lot of opportunities to (inadvertently as it may be) write ugly code.  But I think that's going to be true no matter what approach you take.  So it's best to enter a project with a few carefully selected MVP/MVC design patterns and have a naming convention to reflect which technique is being used when.  Although MVP with ASPX-as-view-initializers is a very powerful technique on complicated pages, it can be a bit overkill if all you need to do is spit out a list of a few items.


Matty74 wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-11-2007 10:28 PM


Thanks for the feedback I'll let you know how I go with the pattern in my application.


Matty74 wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-12-2007 7:31 PM


I added a button in the datagrid in the ListCustomersView using the OnItemCommand event.

I set up    

presenter.EditCategoryEvent += new DataGridCommandEventHandler(HandleEditCategoryEvent);

HandleEditCategoryEvent(object sender, DataGridCommandEventArgs e)    

in the aspx page.

I declared a  

public DataGridCommandEventHandler EditCategoryEvent;

       public void EditCategory()


           EditCategoryEvent(this, null);


in the Presenter

Now when trigger the event I get

Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation="true"/> etc...

In this Pattern I suspect that the view state is effected the requesting control looses it's ID. Did you come across this problem when implementing the example? If so can you recommend and appraoch to a work around?



Billy McCafferty wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-12-2007 10:23 PM

I did come across that error and, in fact, added <pages enableEventValidation="false" /> to my web.config.  (You may come across this problem with Atlas as well.)  This certainly fixed the problem...but I also had low concers about any security holes this may have created as it's an intranet application.  There's some good discussion (at least some) concerning this issue at

Matty74 wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-13-2007 8:42 PM


I have set up I page to display the 3 different views, now when I do a post back I'm no longer redirecting to a specific page but posting back to the existing page. The problem here is that when I trigger the postback event I no longer have a reference to the presenter, as it was created on page load.

what I have done is saved the presenter in the session and then calling it on post back event firing. Can you see any issues with this appraoch?


Billy McCafferty wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-13-2007 11:01 PM


Why is it a problem to just recreate the presenter upon postback?  The presenter shouldn't maintain any state outside of the page life-cycle.  I've run into the problem that I believe your describing; wherein, you have multiple views but you only care about the IsPostBack of the view on which the submit button was clicked.  One approach that's worked well is to add a hidden input on the view with the submit that identifies the view.  (The value of this hidden input could translate to an enum to give a little more compile time checking in the code-behind.)  Within the ASPX view-initializers, you can then pass IsPostBack or ! IsPostBack to the presenter's InitView based on if the value in the hidden input matches the appropriate view's presenter.  In this way, it's as if it's ! IsPostBack to every presenter except to the one who had the view with the submit button clicked.  Does that make sense?  (You could also automate the hidden input mechanism within a BaseUserControl class so that you don't have to worry about forgetting - or maintaining - the technique.)

Matty74 wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-14-2007 1:39 AM


I tried that it was giving the the <pages enableEventValidation="false" /> error see i have an image button in the grid when I have stored in the session it works. Now when I trigger the event get my args etc.. get my dao all works well until I go to set the visibility of a panel

       private void HandleEditCustomerEvent(object sender, GridCommandEventArgs e)


           listCustomerView.Visible = false;

           object id = e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["Id"];


editCustomerView.Visible = true;


it fails to set the visibility on the views I'm missing something here.


Matty74 wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-14-2007 7:50 PM


In resonlving this I have created IPresenter Interfaces and IView interfaces and created a factory to create the Presenters called from the page base. Events are in some cases handled by the view and not bubbling the event to the aspx, buy calling the InitView from the view directly when an event is fired.

     presenter = ((BasePage) Page).GetPresenter(this, "Customer") as CustomerPresenter;

           object id = e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["Id"];

           presenter.InitViewForEditing(id.ToString(), true);

           pnlEdit.Visible = true;

           pnlGrid.Visible = false;

Billy McCafferty wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-14-2007 11:56 PM

The additional service layer for creating presenters is an interesting approach.  Please let me know how your experiences are with it after a bit more time.  After doing MVP for about a year, I'm only now seeing some subtle but difficult maintenance issues which I'm currently trying to resolve.  I'll post more as I come do some satisfactory conclusions.

Matty74 wrote re: Inject DI Container into Domain Objects with NHibernate
on 02-15-2007 5:36 PM


What about registering the castle container with a webservice, do you know how to or know of an article explaining how to do this? I have 3 web services I want to consume, but not too sure the best way about doing this.


Gunnar wrote re: Inject DI Container into Domain Objects with NHibernate
on 03-01-2007 4:57 PM


I've recently used the same model, but instead of injecting the container itself, Dao instances are injected from the container. For extra performance, the instances can be held (cached) by the IInterceptor instance.

Matt wrote re: Inject DI Container into Domain Objects with NHibernate
on 03-07-2007 11:06 PM


I'm adding a query method to the GenericNHibernateDao class


    public List<T> Find(string queryString)


           List<T> results;

           //ISession s = GetCurrentSession();



               results = session.CreateQuery(queryString).List<T>();




              // CloseSession(s);


           return results;



The problem I'm having is returning a generic List from the CreateQuery method, it does not accept a generic type


have you done this before Bill? If so what appraoch to take.


Matt wrote re: Inject DI Container into Domain Objects with NHibernate
on 03-08-2007 12:36 AM


Stupid question I found your convert to List<T> method.

Another question I am implementing a membership provider on your pattern I have created all the objects and implemented the methods in the genericNHibernateDao.

But I'm not sure where the provider fits with the castlewindsor container, do I jus keep the provider in the core or havee it as apart of the MVP web framework? how would you approach the problem?


Jacob wrote re: Inject DI Container into Domain Objects with NHibernate
on 03-11-2007 4:02 AM


I saw you found a solution to your problem, but I believe adding a cast to your CreateQuery would make your code work as well, i.e.

results = (List<T>)session.CreateQuery(queryString).List<T>();

I got it to work with NHibernate 1.2 Beta3.


Billy McCafferty wrote re: Inject DI Container into Domain Objects with NHibernate
on 03-12-2007 10:14 AM


Damon Carr has done some work with respect to a membership provider that you may want to look at:

This may be a good place to start...he's also great about thoroughly answering questions if you'd like to add to the thread there.

Steve wrote re: Inject DI Container into Domain Objects with NHibernate
on 03-22-2007 7:08 AM


Would this help solve the xmlserialization problem with NHibernate and Web Services?

With Lazy="true", it complains of parameterless constructors with the proxy

Billy McCafferty wrote re: Inject DI Container into Domain Objects with NHibernate
on 03-22-2007 11:44 AM

As I don't have to (get to?) mess around with web services too much, I'll have to leave it to you to do the damage! ;)  But please let me know if you do have good results as I often get questions concerning NHibernate and web services.


About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Google Reader or Homepage Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of
Red-Gate Tools For SQL and .NET


SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
NHibernate Profiler
Balsamiq Mockups
JetBrains - ReSharper
Web Sequence Diagrams
Ducksboard<-- NEW Friend!


Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers


Community Server (Commercial Edition)