Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7625547
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T05:12:24+00:00 2026-05-31T05:12:24+00:00

I am pretty new with DI and IoC pattern. public class LazySessionContext { private

  • 0

I am pretty new with DI and IoC pattern.

public class LazySessionContext
{
    private readonly ISessionFactoryImplementor factory;
    private const string CurrentSessionContextKey = "NHibernateCurrentSession";

    public LazySessionContext(ISessionFactoryImplementor factory)
    {
        this.factory = factory;
    }

    /// <summary>
    /// Retrieve the current session for the session factory.
    /// </summary>
    /// <returns></returns>
    public ISession CurrentSession()
    {
        Lazy<ISession> initializer;
        var currentSessionFactoryMap = GetCurrentFactoryMap();
        if (currentSessionFactoryMap == null ||
            !currentSessionFactoryMap.TryGetValue(factory, out initializer))
        {
            return null;
        }
        return initializer.Value;
    }

    /// <summary>
    /// Bind a new sessionInitializer to the context of the sessionFactory.
    /// </summary>
    /// <param name="sessionInitializer"></param>
    /// <param name="sessionFactory"></param>
    public static void Bind(Lazy<ISession> sessionInitializer, ISessionFactory sessionFactory)
    {
        var map = GetCurrentFactoryMap();
        map[sessionFactory] = sessionInitializer;
    }

    /// <summary>
    /// Unbind the current session of the session factory.
    /// </summary>
    /// <param name="sessionFactory"></param>
    /// <returns></returns>
    public static ISession UnBind(ISessionFactory sessionFactory)
    {
        var map = GetCurrentFactoryMap();
        var sessionInitializer = map[sessionFactory];
        map[sessionFactory] = null;
        if (sessionInitializer == null || !sessionInitializer.IsValueCreated) return null;
        return sessionInitializer.Value;
    }

    /// <summary>
    /// Provides the CurrentMap of SessionFactories.
    /// If there is no map create/store and return a new one.
    /// </summary>
    /// <returns></returns>
    private static IDictionary<ISessionFactory, Lazy<ISession>> GetCurrentFactoryMap()
    {
        var currentFactoryMap = (IDictionary<ISessionFactory, Lazy<ISession>>)
                                HttpContext.Current.Items[CurrentSessionContextKey];
        if (currentFactoryMap == null)
        {
            currentFactoryMap = new Dictionary<ISessionFactory, Lazy<ISession>>();
            HttpContext.Current.Items[CurrentSessionContextKey] = currentFactoryMap;
        }
        return currentFactoryMap;
    }
}

public interface ISessionFactoryProvider
{
    IEnumerable<ISessionFactory> GetSessionFactories();
}

public class SessionFactoryProvider
{
    public const string Key = "NHibernateSessionFactoryProvider";
}

public class NHibernateSessionModule : IHttpModule
{
    private HttpApplication app;

    public void Init(HttpApplication context)
    {
        app = context;
        context.BeginRequest += ContextBeginRequest;
        context.EndRequest += ContextEndRequest;
        context.Error += ContextError;
    }

    private void ContextBeginRequest(object sender, EventArgs e)
    {
        var sfp = (ISessionFactoryProvider)app.Context.Application[SessionFactoryProvider.Key];
        foreach (var sf in sfp.GetSessionFactories())
        {
            var localFactory = sf;
            LazySessionContext.Bind(
                new Lazy<ISession>(() => BeginSession(localFactory)),
                sf);
        }
    }

    private static ISession BeginSession(ISessionFactory sf)
    {
        var session = sf.OpenSession();
        session.BeginTransaction();
        return session;
    }

    private void ContextEndRequest(object sender, EventArgs e)
    {
        var sfp = (ISessionFactoryProvider)app.Context.Application[SessionFactoryProvider.Key];
        var sessionsToEnd = sfp.GetSessionFactories()
                               .Select(LazySessionContext.UnBind)
                               .Where(session => session != null);

        foreach (var session in sessionsToEnd)
        {
            EndSession(session);
        }
    }

    private void ContextError(object sender, EventArgs e)
    {
        var sfp = (ISessionFactoryProvider)app.Context.Application[SessionFactoryProvider.Key];
        var sessionstoAbort = sfp.GetSessionFactories()
                                .Select(LazySessionContext.UnBind)
                                .Where(session => session != null);

        foreach (var session in sessionstoAbort)
        {
            EndSession(session, true);
        }
    }

    private static void EndSession(ISession session, bool abort = false)
    {
        if (session.Transaction != null && session.Transaction.IsActive)
        {
            if (abort)
            {
                session.Transaction.Rollback();
            }
            else
            {
                session.Transaction.Commit();
            }
        }
        session.Dispose();
    }

    public void Dispose()
    {
        app.BeginRequest -= ContextBeginRequest;
        app.EndRequest -= ContextEndRequest;
        app.Error -= ContextError;
    }
}

I got this sample by chinooknugets and jfmarillo from GitHub. From the code above I am injecting the session into repository and controlling the transaction via IHttpmodule. Now there are two concerns for me:

  1. If I implement the transaction management via the code above it would be called whenever there is a request and it would open a session for that request. That’s the sole purpose of implementing “Session Per Request” approach. But what if among all my controller methods I have only one method which actually uses the repository then I don’t want to open the session every time I make a request. Only during the actions which are marked by Transaction attribute in controller would handle the transaction.

  2. I would make a request and session would be opened only when the repository requests for it, so can it be implemented via any IoC container.

  3. I still want the httpcontext events to handle the transaction so that context+=BegingRequest and context+=EndRequest. and the transaction would be handled inside that httpmodule with the httpcontext on request. But I don’t want to implement IhttpModule and put into web.config. Is there any other alternative for this approach ?

  4. The session opening and closing would be done solely inside those httpcontext only however I want to manage it via an IoC container (preferably ninject) but only when the repository is being requesting for that session. Mind it the repository may be initialised when the controller is invoked but that shouldn’t open the session inside that repository. The session should open when actually repository is performing any transient actions.

Would someone clarify what practise should I follow for this scenario? I am using Mvc 3 with ninject and nhibernate.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T05:12:25+00:00Added an answer on May 31, 2026 at 5:12 am

    1, 2)
    Ninject allows Lazy object creation using Ninject.Extensions.Factory 3.0.0

    class MyController
    {
        public MyController(Lazy<SomeRepository> repository) { ... }
    }
    

    This way the repository (and the context) is created when used.

    3)
    Why do you want to use a HttpModule for this? There are much easier ways e.g.:

    kernel.Bind<ISession>()
          .ToMethod(ctx => ctx.Kernel.Get<ISessionFactory().OpenSession())
          .InRequestScope()
          .OnActivation(session => OpenTransaction(session))
          .OnDeactivation(session => EndTransaction(session));
    

    Starting from Ninject 3.0.0 you can add a binding for HttpModules instead of registering them in the web.config and use construcotr injection for them. But since the HttpModule has no knowledge if the context is used you have to open the transaction for all requests.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am pretty new to Unity & IoC in general & as usual, I
I'm pretty new to IoC, Dependency Injection and Unit Testing. I'm starting a new
I am pretty new to the whole DI/IoC thing, so bear with me... I
Im pretty new to Java Web Services, but I cant find a good explanation
I pretty new to Objective-C (and C itself) and need to consume a NSData
I'm pretty new to my company (2 weeks) and we're starting a new platform
I'm a pretty new C# and .NET developer. I recently created an MMC snapin
I'm pretty new to the idea of recursion and this is actually my first
I am pretty new to php, but I am learning! I have a simple
I am pretty new to VB.NET - and I'm struggling to convert the signature

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.