I am fairly new to Ninject as well and DI in general. I use NHibernate as my ORM for my MVC app and have been quite happy with my results. That is, until I upgraded from Ninject 2.1 to 2.2.

Now, I get errors within my NinjectWebsiteApplication class due to using Ninject’s Kernel as a resource locator.

Example:

 void NinjectWebsiteApplication_BeginRequest(object sender, System.EventArgs e)
 {
     ILogger logger = Kernel.Get<ILogger>();
     logger.Debug(“**********REQUEST BEGIN****************”);
     logger.Debug(“**** URL = ” + Request.Url.AbsolutePath);
 }

Example 2:

protected override void OnApplicationStarted()
{
    var bootstrapper = Kernel.Get<Bootstrapper>();
    bootstrapper.RegisterAllAreas();
    AreaRegistration.RegisterAllAreas();
    ......
    (More stuff here, like AutoMapper mappings, etc.)
    ......
}

*The Bootstrapper class is a class I created where I register my routes, global filters, etc.

In both of the above examples, I receive a warning about the Kernel.Get() functions that states the following:

'Ninject.Web.Mvc.NinjectHttpApplication.Kernel' is obsolete: "Do not use Ninject as Service Locator"

After conducting several searches on this, the general consensus is that this is true.

I am trying to work around this, but am at a bit of a loss as to what to do.

I loaded the newest Ninject.Web.Mvc NuGet package which creates the NinjectMVC3 static class under the App_Start folder. I see that they're referencing Microsoft.Web.Infrastructure.DynamicModuleHelper, but I don't see where that fits in to what I'm trying to do.

If anyone has any hints that will help me fix my little mess, I would greatly appreciate it!

有帮助吗?

解决方案

The way to deal with the first is not to use the NinjectWebsiteApplication_BeginRequest event but to write a custom global action filter:

public class LogActionFilterAttribute : ActionFilterAttribute
{
    private readonly ILogger _logger;
    public LogActionFilterAttribute(ILogger logger)
    {
        _logger = logger;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        _logger.Debug("**********REQUEST BEGIN****************");
        _logger.Debug("**** URL = " + filterContext.HttpContext.Request.Url.AbsolutePath);
    }
}

and then in your App_Start/NinjectMVC3.cs:

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<ILogger>().To<Logger>();
    kernel.BindFilter<LogActionFilterAttribute>(FilterScope.Global, 1);
} 

Don't forget to add using Ninject.Web.Mvc.FilterBindingSyntax; in order to bring the BindFilter<> extension method into scope.

And since you have access to the kernel inside the RegisterServices method which happens at application startup you could wire up everything else including your bootstrapper, ...

As far as your Global.asax is concerned you no longer use any Ninject specific stuff in it. You should not derive from NinjectApplication.

The WebActivator infrastructure allows you to have a separate initialization method.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top