ravi
ravi

Reputation: 133

Ninject Load method

I have taken the reference of this example from the link below.

http://blog.prabir.me/post/Dependency-Injection-%28DI%29-e28093-Hello-World-with-Ninject.aspx

using Ninject.Modules; 
using Prabir.NinjectSample.Provider;
using Prabir.NinjectSamples.Providers.ConsoleWriter;
using Prabir.NinjectSample.Providers.MessageBoxWriter;

namespace Prabir.NinjectSample.ConsoleApplication
{
 public class XDocModule : NinjectModule
{

    public override void Load()
    {
        Bind<IWriter>().To<ConsoleWriter>();
        Bind<XDoc>().ToSelf().InSingletonScope();
    }

}
}

In the Load() method, ConsoleWriter is being wired up with IWriter. It looks static and hardcoded. i.e. every time I call IWriter, it will initialize ConsoleWriter. What if I want to use MessageBoxWriter as well. I will have to change the code in Load() method to achieve that. Am I missing anything or it is how Ninject behaves?

Furthermore, Load() method will be called by all types of wiring up. In some other class, I might need to wire ConsoleReader with IReader. In that case, the same

Bind<IWriter>().To<ConsoleWriter>()
Bind<XDoc>().ToSelf().InSingletonScope()

will also be hit. Is this the expected way of Ninject?

Let me explain my question in more details. Lets say I have an interface given below.

public interface IVehicle
{
 PrintSpecification();
}

I have three classes implementing above interface. They could be as shown.

public class Car implements IVehicle
{      
 public void PrintSpecification()
 { Console.WriteLine("Specification for Car");}
}

public class Bus implements IVehicle
{
  public void PrintSpecification()
  { Console.WriteLine("Specification for Bus");}
}

public class Truck implements IVehicle
{
  public void PrintSpecification()
  { Console.WriteLine("Specification for Truck");}
}

Now in my main program, I will have something like this. Here I have used new operator to create three concrete implementations of Car, Bus and Truck. I have to display the specification of all three vehicles. Now I wonder how do I write my Ninject codes so that there is no dependency of the concrete classes.

Public static void main()
{
  IVehicle v1=new Car();
  IVehicle v2=new Bus();
  IVehicle v3=new Truck();
  v1.PrintSpecification();
  v2.PrintSpecification();
  v3.PrintSpecification();
}

Upvotes: 0

Views: 1544

Answers (2)

Daniel Marbach
Daniel Marbach

Reputation: 2314

Your second question can be solved like this

In your ninject module

Bind<IVehicle>().To<Car>();
Bind<IVehicle>().To<Bus>();
Bind<IVehicle>().To<Truck>();
Bind<IVehicleCarPark>().To<CarPark>();

In a class which is retrieved with ninject

public class CarPark : IVehicleCarPark
{
   Ctor(IEnumerable<IVehicle> vehicles) {
       // vehicles will be autoresolved
   }
}

Upvotes: 0

mipe34
mipe34

Reputation: 5666

Module loading should be done once on the application startup (or you can load modules dynamically per request - when it is needed, but it is not probably your case).

If you want to use various implementations of your interface on different places you can use conditional binding.

Conditional binding:

Bind<IWriter>().To<ConsoleWriter>().When(x=> ReturnTrueWhenConditionMet());

Or you can use naming and NamedAttribute:

Named attribute:

Binding

Bind<IWriter>().To<ConsoleWriter>().Named("ConsoleWritter");

Constructor of class where ConsoleWritter will be injected.

public MyClassWithConcoleWritter([Named("ConsoleWritter")] IWriter writer)
{
}

Problem with NamedAttribute is that it will tie you to Ninject in your bussines classes, so there would be problem to easy switch the IOC container if you need to do so.

However there are even more options how to do conditional binding. See this document for more information - Contextual binding.

Upvotes: 2

Related Questions