views:

173

answers:

1

I'm using ASP.NET MVC + NHibernate + Fluent NHibernate and having a problem with lazy loading.

Through this question (http://stackoverflow.com/questions/2519964/how-to-fix-a-nhibernate-lazy-loading-error-no-session-or-session-was-closed), I've discovered that I have to implement the Open Session in View pattern , but I don't know how.

In my repositories classes, I use methods like this

    public ImageGallery GetById(int id) {
        using(ISession session = NHibernateSessionFactory.OpenSession()) {
            return session.Get<ImageGallery>(id);
        }
    }

    public void Add(ImageGallery imageGallery) {
        using(ISession session = NHibernateSessionFactory.OpenSession()) {
            using(ITransaction transaction = session.BeginTransaction()) {
                session.Save(imageGallery);
                transaction.Commit();
            }
        }
    }

And this is my Session Factory helper class:

public class NHibernateSessionFactory {
    private static ISessionFactory _sessionFactory;
    private static ISessionFactory SessionFactory {
        get {
            if(_sessionFactory == null) {
                _sessionFactory = Fluently.Configure()
                    .Database(MySQLConfiguration.Standard.ConnectionString(MyConnString))
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<ImageGalleryMap>())
                    .ExposeConfiguration(c => c.Properties.Add("hbm2ddl.keywords", "none"))
                    .BuildSessionFactory();
            }
            return _sessionFactory;
        }
    }
    public static ISession OpenSession() {
        return SessionFactory.OpenSession();
    }
}

Someone could help me to implements Open Session in View pattern?

Thank you.

+1  A: 

This is already asked before, but I don't remember where to find it. When you do the following or something similar, you have what you want and some code duplication reduce in your repositories as bonus.

THIS IS A LINE TO PREVENT A CODE FORMATTING BUG IN STACKOVERFLOW: CODEFORMATTING DOES NOT WORK AFTER A LIST

public class Repository
{
  private readonly ISession session;

  public Repository()
  {
    session = CurrentSessionContext.CurrentSession();
  } 

  public ImageGallery GetById(int id) 
  {
    return session.Get<ImageGallery>(id);
  }

  public void Add(ImageGallery imageGallery)
  {
    session.Save(imageGallery);
  }
}

You can also manage the session with an ioc container and a unit of work wrapper instead of the current session context.

Paco
Thank you. It has worked very well!
MCardinale
I recommend using manual dependency injection for your repository classes. That is, pass the ISession into the repository's constructor.
Jamie Ide
The only reason for "manual dependency injection" is unit testing. It has no loose coupling like resolving the dependency with automatic injection.
Paco