Search code examples
c#ninjectioc-container

Constructor with multiple arguments with Ninject


I am tring to use Ninject as a IoC container but could not understand how to create an instance of a class that has more than 1 parameter in the constructor. Basically I have a service interface for authentication in a PCL library and its implementation in a WP8 project that receives in the constructor the cosumer key, secret and baseAddress:

//On PCL project
public interface IAuthorizationService {
 bool Authenticate();
}

//On WP8 Project
pubilc class MyAuthenticator : IAuthorizationService {
 public MyAuthenticator(string consumerKey, string consumerSecret, string baseAddress) { ... }
 public bool Authenticate() { ... }
}

Now I need to configure Ninject module so I can get an instance of IAuthorizationService. If my class had no constructors I would do:

internal class Module : NinjectModule {
 public override void Load() {
  this.Bind<IAuthorizationService>().To<MyAuthenticator>();
 }
}

If it had fixed values for the constructor I would do:

internal class Module : NinjectModule {
 public override void Load() {
  this.Bind<IAuthorizationService>().To<MyAuthenticator>().WithConstructorArgument( */* fixed argument here*/* );
 }
}

And to get an instance Module.Get<IAuthorizationService>()

But what if the constructor parameters cannot be resolved at compile time? How to pass the paramenters? How should the bind code be?

Edited to claryfy the question.


Solution

  • It's very easy. No matter how many constructor arguments, the binding stays the same:

    Bind<IAuthorizationService>().To<MyAuthenticator>();
    

    Let's say MyAuthenticator had a constructor with one parameter of type IFoo. All you got to do is tell ninject how it can resolve/create an IFoo. Again, very simple:

    Bind<IFoo>().To<Foo>();
    

    You don't need WithConstructorArgument ever, except in case you want to override the default behavior of ninject. Let's say MyAuthenticator has a parameter of type IFoo plus another parameter string seed which you want to configure specifically. All you'd need is:

    Bind<IFoo>().To<Foo>();
    Bind<IAuthorizationService>().To<MyAuthenticator>()
        .WithConstructorArgument("seed", "initialSeedValue");
    

    no need to specify the value of the IFoo parameter!