How to use Ninject with HttpClient
Asked Answered
S

2

6

What would be the recommended way to use Ninject to inject the same HttpClient object to all Controller instances in an application?

Currently, I am injecting an EntityFramework Database context following Adam Freeman's MVC book as follows. However, this creates a new dbContext for each controller instance, which is probably not ideal for HttpClient, since HttpClient is meant to be reused across all controllers in an MVC application.

Constructor:

public class AccountController : Controller
{
  MyDBContext dbContext = new MyDBContext();

  public AccountController(MyDBContext context)
  {
    dbContext = context;
  }

  ...
}

And the Ninject Factory is as follows:

/// Class based on Adam Freeman's MVC book to use dependency injection to create controllers
public class NinjectControllerFactory : DefaultControllerFactory
{
  private IKernel ninjectKernel;

  public NinjectControllerFactory()
  {
    ninjectKernel = new StandardKernel();
    AddBindings();
  }

  protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
  {
    return controllerType == null
      ? null
      : (IController)ninjectKernel.Get(controllerType);
  }

  private void AddBindings()
  {
    ninjectKernel.Bind<MyDBContext>().ToSelf().InTransientScope();        
  }
}
Sande answered 1/1, 2017 at 1:53 Comment(0)
H
2

You just have to change your configuration to:

ninjectKernel.Bind<MyDBContext>().ToSelf().InRequestScope();

For more information about request scoping, please read this.

Hexyl answered 2/1, 2017 at 9:55 Comment(0)
S
2

Thanks Steven. Currently, I find that the following works. I created a static HttpClient property in the NinjectController and bound it as constant in singleton scope. Daniel's book was helpful in better understanding Ninject.

/// Class based on Adam Freeman's MVC book to use dependency injection to create controllers
public class NinjectControllerFactory : DefaultControllerFactory
{
  private IKernel ninjectKernel;
  private static HttpClient WebAPIClient; // added

  public NinjectControllerFactory()
  {
    ninjectKernel = new StandardKernel();

    WebAPIClient = new HttpClient();  // added
    WebAPIClient.BaseAddress = new Uri("http://localhost:1153");  // added 

    AddBindings();
  }

  protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
  {
    return controllerType == null
      ? null
      : (IController)ninjectKernel.Get(controllerType);
  }

  private void AddBindings()
  {
    ninjectKernel.Bind<MyDBContext>().ToSelf().InTransientScope();
    ninjectKernel.Bind<HttpClient>().ToConstant(WebAPIClient).InSingletonScope();  // added
  }
}
Sande answered 2/1, 2017 at 16:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.