1
votes

I am new with Ninject. Can someone help me to achieve what I want. I will give you my example. Please help me how you use NInject to get loose coupling.

Lets say I have an interface given below.

public interface IVehicle
{
 PrintSpecification();
}

Now 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();
}
2
response is: it depends on how you would choose between the different implementation in your app... - Felice Pollano

2 Answers

2
votes

You can bind all specifications in this way:

public class AutoModule : NinjectModule
{
    public override void Load()
    {
        Bind<IVehicle>().To<Car>();
        Bind<IVehicle>().To<Bus>();
        Bind<IVehicle>().To<Truck>();
    }
}

and in your app:

IKernel kernel = new StandardKernel(new AutoModule());

kernel.Bind<Inspector>().ToSelf();

class Inspector
{
      IVehicle[] vehicles;
      public Inspector(IVehicle[] vehicles)
      {
          this.vehicles=vehicles;
      }
      public void PrintSpecifications()
      {
           foreach(var v in vehicles )
           {
              v.PrintSpecification();
            }
      }
}

//automatic injection in constructor
kernel.Get<Inspector>().PrintSpecifications();

If you want some way to bind conditionately one implementation you can use

  • Named Bindings
  • Conditional Bindings
  • Contextual Bindings

There is a good documentation inthe NInject wiki.

If you need to map multiple tyes in your module, consider using some naming convention and create some automatic binding strategies.

You should also do some effort in being decoupled from the IoC container too, have a look on how the Composition Root Pattern works.

1
votes

Create module with named bindings for IVehicle implementations:

public class AutoModule : NinjectModule
{
    public override void Load()
    {
        Bind<IVehicle>().To<Car>().Named("Small");
        Bind<IVehicle>().To<Bus>().Named("Big");
        Bind<IVehicle>().To<Truck>().Named("Huge");
    }
}

And get your vehicles by name:

IKernel kernel = new StandardKernel(new AutoModule());
IVehicle v1 = kernel.Get<IVehicle>("Small");
IVehicle v2 = kernel.Get<IVehicle>("Huge");
IVehicle v3 = kernel.Get<IVehicle>("Big");
v1.PrintSpecification();
v2.PrintSpecification();
v3.PrintSpecification();