简体   繁体   English

如何使用Ninject实现松散耦合

[英]How to achieve Loose coupling using Ninject

I am new with Ninject. 我是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. 请帮助我如何使用NInject来松耦合。

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 . 在这里,我使用new运算符创建了CarBusTruck三个具体实现。 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. 现在我想知道如何编写Ninject代码,以便不依赖于具体类。

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

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 . 在NInject wiki中有一个很好的文档

If you need to map multiple tyes in your module, consider using some naming convention and create some automatic binding strategies. 如果需要在模块中映射多个tyes,请考虑使用某些命名约定并创建一些自动绑定策略。

You should also do some effort in being decoupled from the IoC container too, have a look on how the Composition Root Pattern works. 你也应该做一些与IoC容器分离的工作,看看组合根模式是如何工作的。

Create module with named bindings for IVehicle implementations: IVehicle实现创建具有命名绑定的模块:

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM