1

I'm developing an application (asp.net mvc) and I'm using ISession per request (in globa.asax I use Bind and Unbind in Begin_Request event and End_Request event). Everything works fine but sometimes (some requests) I don't need to use an ISession (a connection with database).

I'd like to know if is there any way to open an ISession only when I need and make the ISession entry in all process request (to be shared with all repositories and a unique context of transaction) ?

I'm developnig and penny auction website and my server will have many request per second and sometimes I don't need the connection, I'll use a Cache.

Thanks

Cheers

Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194

2 Answers2

2

You can use an ActionFilter to do this. Here's one that I use to do exactly what you describe.

public class UsingNhibernate : ActionFilterAttribute {
    private ISession nhSession;
    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        nhSession = NHHelper.OpenSession();
        nhSession.BeginTransaction();
        // set an accessible reference to your nhSession for access from elsewhere
        //   ((ApplicationController)filterContext.Controller).nHSession = nhSession; is what I do
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        try {
            if (filterContext.Exception == null && nhSession != null && nhSession.Transaction.IsActive)
                nhSession.Transaction.Commit();
            else if (nhSession != null && nhSession.Transaction.IsActive)
                nhSession.Transaction.Rollback();
        } catch (Exception ex) {
            if (nhSession != null && nhSession.Transaction.IsActive)
                nhSession.Transaction.Rollback();
            nhSession.Dispose();
            throw;
        }
        nhSession.Dispose();
        base.OnActionExecuted(filterContext);
    }
}

On each appropriate controller action (or even at the controller level to apply to all actions) you simply add the UsingNhibernate action filter like so:

[UsingNhibernate]
public ActionResult SaveSystemSetting(SystemAdminVM item) {
Tahbaza
  • 9,486
  • 2
  • 26
  • 39
2

It should be noted that opening a session does not imply opening a connection to the database. As noted in this article, the cost of opening a session is extremely low. So, in general, I wouldn't worry about requests opening a session when they don't need it; essentially you're just newing up a very lightweight object.

DanP
  • 6,310
  • 4
  • 40
  • 68
  • I didn't know about that, maybe it doesn't have a problem. Thanks! – Felipe Oriani Sep 14 '10 at 11:32
  • I can highly recommend NHProf if you need to have a birds-eye view of what's happening under the covers with NHibernate. If nothing else, this should help to verify that no database interaction is taking place in the emtpy sessions. – DanP Sep 14 '10 at 11:43
  • Hi @DanP, Yes, I'm using NHProf to see with more details, and really some pages I get a empty session. I'll implement the chronometer for penny auction and each second my app will have a request. Just like you recommand and Ayenge article, it will not be a problem =D. Thanks – Felipe Oriani Sep 14 '10 at 12:16