views:

32

answers:

2

Hi Friends, 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

+1  A: 

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
+1  A: 

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
I didn't know about that, maybe it doesn't have a problem. Thanks!
Felipe
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
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