Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ninject OnePerRequestBehaviour doesn't seem to work correctly?

I've been using Ninject as my IOC in my web app. It's great and I think it works really well, however I have been trying to register some interfaces / classes as OnePerRequestBehaviour but it doesn't seem to actually use the behaviour. The code runs correctly but in one of my classes it lazy loads page information from the database then once it has been loaded it doesn't need to hit the database.

My problem is that the lazily loaded property will load in my first request, when I then request the next page the same instance of the class is used. The reason I know this is because the class is not instantiated again and the lazily loaded property is already set.

This code is within my module class :

public class NinjectModule : StandardModule
{
    public override void Load()
    {
        Bind<IUnitOfWorkDataStore>().To<HttpContextDataStore>().Using<OnePerRequestBehavior>();


        Bind<CmsService>().ToSelf().Using<OnePerRequestBehavior>();
        Bind<CmsRepository>().ToSelf().Using<OnePerRequestBehavior>();
    }
}

Then inside my Global.asax which inherits from NinjectHttpApplication I have the following:

        protected override IKernel CreateKernel()
        {
            OnePerRequestModule module = new OnePerRequestModule();
            module.Init(this);

            KernelOptions options = new KernelOptions();
            options.InjectNonPublicMembers = true;

            IKernel kernel = new StandardKernel(options, new NinjectModule());

            return kernel;
        }

The first call made to CmsService is within the global.asax as well on authenticate_request:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            if (HttpContext.Current.Request.Url.AbsoluteUri.Contains(".aspx") &&
                !HttpContext.Current.Request.Url.AbsoluteUri.Contains(".aspx/"))
            {
                CmsService facCMS = HttpKernelFactory.Get<CmsService>();
                ContentPage page = facCMS.GetCurrentPage();

                // DO Logic based on the page being brought back
            }
        }

The above GetCurrentPage() code:

public ContentPage GetCurrentPage()
{
    if (_currentPage != null)
        return _currentPage;

    return GetCurrentPage(_isAdmin);
}

So as you can see the _currentPage variable is only loaded if it hasn't been set before, which should be once per request, however Ninject doesn't seem to be creating the CmsService per request it seems to create it for an abritrary amount of time.

Deos anyone have any idea of why this isn't working for me or any example code of where it definately does work?

Thanks

like image 880
John_ Avatar asked Feb 11 '09 09:02

John_


1 Answers

The OnePerRequestModule is an HttpModule, and needs to be loaded into your ASP.NET pipeline in order to work. If you add it to your web.config, it should work:

IIS7:

<system.webServer> 
  <modules>
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
  </modules>
</system.webServer>

IIS6:

<system.web>
  <httpModules>
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
  </httpModules>
</system.web>

The OnePerRequest behavior is greatly improved in Ninject2 (which is yet to be released).

like image 84
Nate Kohari Avatar answered Nov 12 '22 14:11

Nate Kohari