views:

278

answers:

4

Hello,

I'm trying to set up NHibernate in an ASP.NET MVC application using a DDD approach. However, I do get an error when trying to lazy load an objects related entity. Heres how I've structured my application:

Infrastructure layer: Contains mapping files, repository implementations and a NHibernate bootstrapper to configure and build a session factory.

Heres a repository example:

public class CustomerRepository : ICustomerRepository
{
    public Customer GetCustomerById(int customerId)
    {
        using (var session = NHibernateBootstrapper.OpenSession())
            return session.Get<Customer>(customerId);
    }
}

Domain layer: Has simple POCO classes, repository and service interfaces

Application layer: Contains Service implementations.

Heres a service example:

public class CustomerService : ICustomerService
{
    private ICustomerRepository _repository;

    public CustomerService(ICustomerRepository repository)
    {
        _repository = repository;
    }

    public Customer GetCustomerById(int customerId)
    {
        return _repository.GetCustomerById(customerId);
    }
}

Presentation layer: Contains the ASP.NET MVC application. And this is where I discovered my problem. Using the MVC approach, I have a controller which, using the CustomerService service, gets a customer and displays the customer in a View (strongly typed). This customer has a related entity Contact, and when I try to access it in my View using Model.Contact, where Model is my Customer object, I get an LazyInitializationException.

I know why I get this. It's because the session used to retrieve the Customer in the CustomerRepository is dead by now. My problem is how I can fix this. I would like if I could avoid getting the related Contact entity for the Customer in my repository, because some views only need the Customer data, not the Contact data. If this is possible at all?

So to the question: is it possible to wait querying the database, until the presentation layer needs the related entity Contact?

I think that what I need is something like what this article describes. I just can't figure out how to implement it in infrastructure layer, or where should it be implemented?

Thanks in advance. Any help will be much appreciated!

+1  A: 

As for session management it is common to use single session per request. You can see an example of implementation here. It is an open source project that were designed to setup new asp.net applications with the help of Nhibernate wery easy. source code can be founded here.

Hope it helps.

Sly
A: 

Is the problem related to this?

Jon Seigel
A: 

Are all your properties and methods in your Customer class marked virtual?

How are you opening and closing your session? I use an ActionFilterAttribute called TransactionPerRequest and decorate all my controllers with it.

Check out this for an implementation.

cdmckay
+1  A: 

I also recommend Sharp Architecture.

Another approach, as well as suggestion, is to avoid passing entities to views. There're other problems with it except session management - business rules leaking into views, bloated/spagetti code in there, etc. Use ViewModel approach.

Another problem you'll get is storing your entities in Session. Once you try to get your Customer from Session["customer"] you'll get the same exception. There're several solutions to this, for example storing IDs, or adding repository methods to prevent lazy-loading of objects you're going to store in session - read NHibernate's SetFetchMode - which, of course, you can also use to pass entity to views. But as I said you better stick with ViewModel approach. Google for ViewModel, or refer to ASP.NET MVC In Action book, which uses samples of code from http://code.google.com/p/codecampserver/. Also read this, for example.

queen3