6
votes

I have an ASP.NET MVC app with a simple NinjectModule:

public class MainModule : NinjectModule
{
    public override void Load()
    {
        Bind<AppSettings>().ToSelf().InSingletonScope();
        Bind<HttpContext>().ToMethod(context => HttpContext.Current); // <-- problem
        Bind<MainDbContext>().ToSelf().InRequestScope();
        Bind<UserInfo>().ToSelf().InRequestScope();
    }
}

This is the only binding code in my entire app. When I run my app, I immediately get this runtime error:

Error activating HttpContext
More than one matching bindings are available.
Activation path:
3) Injection of dependency HttpContext into parameter httpContext of constructor of type UserInfo
2) Injection of dependency UserInfo into parameter userInfo of constructor of type HomeController
1) Request for HomeController

Suggestions:
1) Ensure that you have defined a binding for HttpContext only once.

The error message seems to be saying that I've defined the HttpContext binding more than once, but the only binding statements in the entire application are in MainModule, and I've clearly only defined one binding for HttpContext. If I comment out that line of code, I stop getting the error, but the HttpContext that gets injected is not correct (it's an empty, newly instantiated HttpContext rather than HttpContext.Current).

The error message does describe the exact injection sequence I would expect to occur...

HttpContext should get injected into the constructor of UserInfo, which looks like this:

public class UserInfo
{
    private readonly HttpContext _httpContext;

    public UserInfo(HttpContext httpContext)
    {
        _httpContext = httpContext;
    }

    // ... etc ... //
}

And UserInfo should get injected into the constructor of HomeController, which looks like this:

public class HomeController : Controller
{
    private readonly AppSettings _appSettings;
    private readonly UserInfo _userInfo;

    public HomeController(AppSettings appSettings, UserInfo userInfo)
    {
        _appSettings = appSettings;
        _userInfo = userInfo;
        ViewData[Token.AppSettings] = _appSettings;
        ViewData[Token.UserInfo] = _userInfo;
    }

    // ... actions here ... //
}

Why does this result in an error? This seems like a very straightforward dependency injection scenario. In what way am I defining the binding for HttpContext more than once?

2
You've shown us the main module. You havent told us if you're using Ninject.Web.MVC3 and/or where your Kernel is getting created. The error strongly suggests you're executing the module loads into a single Kernel more than once, e.g. by triggering it in you Global / HttpApplication construction/start (of which there are almost always >1).Ruben Bartelink

2 Answers

5
votes

If you are using the Ninject.MVC3 extension than you have to remove

Bind<HttpContext>().ToMethod(context => HttpContext.Current); // <-- problem

because the HttpContext binding is already added by the extension.

1
votes