C# – Add Constructor Arguments To Ninject Binding

cdependency-injectionioc-containerninject

I have an ASP.MVC project where I am using ninject for the IOC container. I have added the binding as a separate class within an Infrastructure folder like this:

public class NinjectControllerFactory : DefaultControllerFactory{

  private readonly IKernel _ninjectKernal;

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

    PSCCheckContext m = _ninjectKernal.Get<PSCCheckContext>(new IParameter[] 
        { new ConstructorArgument("appNamekey", "Name of Staff Application"), 
            new ConstructorArgument("serverLocationNameKey", "Location of Application Server") });

    AddBindings();
  }

So you can see that I am trying to set two parameters from the web.config in the constructor of the PSCCheckContext. This is another C# application that handles access to the db. The AddBindings() class just maps the interface classes to the concrete implementations as you would expect:

private void AddBindings()
{
  ...
  _ninjectKernal.Bind<IPSCCheckContext>().To<PSCCheckContext>();
}

The problem I am having is that there are 2 constructors in the PSCCheckContext class where the second one takes a different parameter:

public class PSCCheckContext : IPSCCheckContext
{
  public PSCCheckContext(string appNamekey, string serverLocationNameKey);
  public PSCCheckContext(string imgNamekey, string imgFlagKey, string serverLocationKeyName);

When I try and hit the controller that Ninject injects this binding I get an error that:

Error activating string. No matching bindings are available, and the type is not self-bindable.

Activation path:
3) Injection of dependency string into parameter imgNamekey of constructor of type PSCCheckContext
2) Injection of dependency IPSCCheckContext into parameter pscCheckContext of constructor of type AccountController
1) Request for AccountController

Suggestions:
1) Ensure that you have defined a binding for string.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.

Even if I change the binding to be better (having read http://thebrainyprofessionals.com/2013/05/20/passing-constructor-parameters-in-ninject/)

IParameter appNamekey = new ConstructorArgument("appNamekey", "Name of Staff Application");
IParameter serverLocationNameKey = new ConstructorArgument("serverLocationNameKey", "Location of Application Server");
_ninjectKernal.Bind<IPSCCheckContext>().To<PSCCheckContext>()
  .WithConstructorArgument(appNamekey)
  .WithConstructorArgument(serverLocationNameKey);

I still get the same error. I have read various SO questions:

Inject value into injected dependency

Creating an instance using Ninject with additional parameters in the constructor

Convention based binding of constructor string arguments with Ninject

but none seem to be having my problem.

What am I doing wrong?

I can't remove the additional constructor as it is in a different application and I think it is being used by a different system.

Here's the AccountController constructor for completeness

public class AccountController : BaseController

  private readonly IPSCCheckContext _pscCheckContext;

  public AccountController(IPSCCheckContext pscCheckContext)
  {
    this._pscCheckContext = pscCheckContext;

Best Answer

You can also try this:

kernel.Bind<IPSCCheckContext>().ToConstructor(ctorArg => new PSCCheckContext(
    "Name of Staff Application", 
    "Location of Application Server"));

I prefer this over WithConstructorArgument, since if you ever change the arg name, your DI binding will not break.

Related Topic