2

I'm trying to use Ninject to manage lifetime on objects. For my IRepository object, I am requiring IDisposable to be implemented, and within the ConcreteRepository, I have implemented IDisposable to kill my NHibernateSession.

My issue is that I also put a static variable within the ConcreteRepository to count the number of instantiations and destructions/disposals of the ConcreteRepository... when I run the application, I'm running out of connections to the database, and my log is showing that my application is never releasing my connections.

My Global.asax:

public class Global : NinjectHttpApplication
{
    protected override void OnApplicationStarted()
    {
        base.OnApplicationStarted();

        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
        ControllerBuilder.Current.DefaultNamespaces.Add("WebPortal.Controllers");

        var log4netConfigFileInfo = new System.IO.FileInfo(Server.MapPath("~/log4net.xml"));

        log4net.Config.XmlConfigurator.ConfigureAndWatch(log4netConfigFileInfo);
        log4net.ILog log = log4net.LogManager.GetLogger(typeof(Global));
        log.Info("Started...");
    }

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }


    protected override Ninject.IKernel CreateKernel()
    {
        var kernel = new Ninject.StandardKernel(
        new Utils.UtilsModule(),
        new Web.DataObjects.NHibernate.DataObjectsNHibernateModule(),
        new Payroll.PayrollModule(),
        new Web.DataObjects.DbModule()
        );

        kernel.Load(Assembly.GetExecutingAssembly());

        return kernel;
    }
}

My Controller module that I'm using to test with:

public class DatabaseAreaModelModule
    : NinjectModule
{
    public override void Load()
    {
        Bind<DiscountEdit>().ToSelf().InRequestScope();
        Bind<ItemCategoryEdit>().ToSelf().InRequestScope();
        Bind<ItemEdit>().ToSelf().InRequestScope();
        Bind<ModifierEdit>().ToSelf().InRequestScope();
        Bind<ModifierSetEdit>().ToSelf().InRequestScope();
        Bind<RevenueCenterEdit>().ToSelf().InRequestScope();
        Bind<RevenueClassEdit>().ToSelf().InRequestScope();
        Bind<TaxEdit>().ToSelf().InRequestScope();
    }
}

My "NHibernate" Ninject module:

public class DataObjectsNHibernateModule
    : NinjectModule
{
    public override void Load()
    {
        Bind<ISessionFactory>().ToProvider<NHibernateSessionProvider>().InSingletonScope();
        Bind<IRepository>().To<NHibernateRepository>().InRequestScope();
    }
}

What I'm trying to figure out is why when I ask for something to be InRequestScope(), it isn't being disposed... any ideas?

Richard B
  • 1,581
  • 1
  • 15
  • 31
  • It may be passing ISessionFactory to my Repository instead of passing ISession to my repository... still looking into it. http://vault13.co.uk/ninject-mvc3-and-web-requests/ – Richard B May 15 '12 at 03:41

2 Answers2

5

In order to get InRequestScope() objects to be disposed when the request is finished, you have to load the OnePerRequestHttpModule.

Honestly, I don't know why everyone feels the need to do things the hard way. Just install Ninject.MVC3 from nuget and it takes care of all this for you. 99.9% of the "please help me, Ninject isn't doing what it's supposed to" questions I see are because people feel the need to do things the hard way and they do it wrong.

Save yourself some headache. Just install Ninject.MVC3 and copy over your bindings and/or modules to NinjectWebCommon.cs and you're done.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • 2
    @blowdart - What's harsh? This is the hard way to do it, and you will probably get it wrong if you don't know what you're doing. Ninject.MVC3 is the easy way, and you get it right, and it takes seconds to install. – Erik Funkenbusch May 15 '12 at 05:47
  • It wound up being in my NHibernateMoudle... notice how I'm not binding an ISession to anything... I was pushing ISessionFactory into my Repository, and it was never disposing from there. Simply binding ISession to a method that got the ISessionFactory.OpenSession(), and pushing ISession into the factory resolved the issues. I did it via Global only because I ran into issues with the Ninject.MVC3 package in the past, and i was trying to correct those issues in case they were still around. – Richard B May 15 '12 at 13:15
  • @RichardB - what issues are you referring to? I'd be more inclined to address the issues than use a workaround. Ninject3 has changed how things work quite significantly. – Erik Funkenbusch May 15 '12 at 15:16
  • @MystereMan, In other words... at one point, I had things working using Global, made the conversion to using the MVC3 package, and it was working after resolving a few PEBCAK issues, but noticed this *one* issue, so I rolled back, still had the issue, and finally found out it was because I was injecting the wrong thing into the wrong area... in all honesty, I can just throw the Ninject.MVC3 Activation class back into the mix, and roll my Global.asax.cs back to being an HttpApplication... It's not that big of a deal. I may just do it anyhow, because I like the nuget deployment model. – Richard B May 15 '12 at 20:55
  • I'm using Ninject.MVC4, added my bindings to `NinjectWebCommon.RegisterServices` and my DbContext which is `InRequestScope()` still doesn't seem to be disposing. What would I check at this point? – epalm Sep 18 '14 at 21:48
  • @epalm - What makes you think it's not being disposed? – Erik Funkenbusch Sep 19 '14 at 01:31
2

Either you use an old version or you haven't loaded any of the web extensions together with Ninject.Web.Common

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Remo Gloor
  • 32,665
  • 4
  • 68
  • 98