Blog Stats
  • Posts - 13
  • Articles - 0
  • Comments - 5
  • Trackbacks - 0

 

Using Template Pattern to solve my Nhibernate Session issue

 

I as I mentioned in my last post, the standard out of the box setup for NHibernate in Asp.Net does not work well with Ajax calls.  The standard approach you will see in the online docs and examples puts the Session.Close() method in the OnEndRequest event handler.  This will work when you're doing PostBacks and probably partial post-backs, but I avoid those (blog entry on why later).  But on a Ajax method call, OnEndRequest will not do it for you since it's not called after your webservice call.

Now I'm sure there is another http module that you might be able to tap into.  I've seen some diagrams of the asp.net ajax event model, but not studied it seriously.  My approach was to check that the session was open before my save method call and close afterwards in my Nhibernate Implementation of my repositories.  In order to reduce repetive code and ensure that I always closed my connection, I used the Template Method Pattern.  There are lots of examples of Template Method on the web, here is the dofactory link to their example: http://www.dofactory.com/Patterns/PatternTemplate.aspx.

The purpose of the Template Method is to break up an algorithm into smaller steps and let subclasses perform parts of the algorithm.  This allows you change the behavior of the method, but keep a consistent api in your system.

Here is the UML Diagram from dofactory.

 

Though I'm not sure how helpful the diagram is.  Here is the specific implementation in how I used it. This is after some refactoring.  I actually started with ISprintRepository and then factored out the Repository<T>.  When creating new repositories, this will ensure some common features and it hides the generic interface to make typing a little easier when instantiating these things

 public interface ISprintRepository : Repository<Sprint>

I then create a NhibernateBaseRepository class that has the following abstract proctected and public methods.

 

protected abstract ValidationResult<T> SaveInternal(T item);

public ValidationResult<T> Save(T item)

{

      try

      {

           CheckConnectionStatus();

           ValidationResult<T> result = SaveInternal(item);

           return result;

      }

      finally

      {

           NHibernateSession.Flush();

           NHibernateSession.Close();

      }

}

 

This is the basic structure of the template method.  Declare your public method in the base class and create abstract or virtual methods to allow your sub classes to fill in the blanks.  Now you implement your concrete class and do the real work in the SaveInternal method. 

protect  ed override ValidationResult<Sprint> SaveInternal(Sprint item)

      ValidationResult<Sprint> result = new ValidationResult<Sprint>();
     
try 
      {
          true
      } 
      catch (System.Exception e) 
      { 
          result.Result =
false
          result.Messages.Add(e.ToString());       return result;
}

 

ISprintRepository sr = new SprintRepository();

vr = sr.Save(spr); 

      } 
      result.Item = item; 

 

That's it in a nutshell.  Now all that is left it so actually use the implementation in your application somewhere. 

 

 

This solves the problem for handling things that have at same method signature like save, update and delete.  But this wouldn't be as pretty for specific query methods like GetByFK(xxx).  I haven't worked this out yet, but I think that I am going to use a delegate approach for this.  I'll let you know as soon as I get something down on paper that I like.  All of this is coming from one of my pet projects I work on in my spare time, so it's not exactly getting done in record time.  But I am making progress.

 

Feedback

# re: Using Template Pattern to solve my Nhibernate Session issue

Gravatar I'm not sure why your EndRequest is not firing, but you got it right that you could use a different HttpModule behavior if the current request was an ajax one.

I would warn you not to keep your session boundary too tight, otherwise you will not be able to take advantage of NHibernate's excellent cache and lazy loading features.

To clarify, you're talking about ASP.NET Ajax right, not ajax calls in general? 8/27/2007 2:08 PM | Ben Scheirman

# re: Using Template Pattern to solve my Nhibernate Session issue

Gravatar I'm using the asp.net ajax library, but I'm not using partial postbacks, I'm making a pure ajax call to a web service. OnEndRequest is definitely not firing.

I thought about whether I wanted to close the session immediatly. I'm still new to NHibernate, but I'm pretty adamant about keeping my insert and updates as atomic as possible in a web application since I don't have as much control about when someone closes the browser as you would in a win app. I can't tell you how many times I've accidently closed the browser when I didn't want to. 8/27/2007 3:20 PM | John

# re: Using Template Pattern to solve my Nhibernate Session issue

Gravatar Yes you definitely don't want to keep the session alive for longer than the current request.

(Session-per-HttpSession used to be popular, but the Session_End event either doesn't get called for 30 minutes after you close your browser, or it doesn't get called at all if your application restarts)

Is your web service in the same project as the web site? They share a web.config? I'm really curious to know why endrequest is not firing. 8/28/2007 11:29 PM | Ben Scheirman

Post a comment





 

 

 

 

Copyright © John Teague