Ninject Load方法

时间:2013-01-10 10:15:46

标签: c# ninject

我从下面的链接中引用了这个例子。

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

}
}

Load()方法中,ConsoleWriter正在与IWriter连接。它看起来像静态和硬编码。即每次拨打IWriter时,它都会初始化ConsoleWriter。如果我也想使用MessageBoxWriter该怎么办?我将不得不更改Load()方法中的代码来实现这一点。 我错过了什么,或者Ninject的表现如何?

此外,所有类型的连线都会调用Load()方法。在其他一些课程中,我可能需要将ConsoleReaderIReader联系起来。在那种情况下,相同的

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

也会被击中。这是Ninject的预期方式吗?

让我更详细地解释一下我的问题。 假设我在下面给出了一个界面。

public interface IVehicle
{
 PrintSpecification();
}

我有三个类实现上面的接口。它们可以如图所示。

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");}
}

现在在我的主程序中,我会有类似的东西。在这里,我使用new运算符创建了Car,Bus和Truck的三个具体实现。我必须显示所有三种车辆的规格。现在我想知道如何编写Ninject代码,以便不依赖于具体的类。

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

2 个答案:

答案 0 :(得分:2)

模块加载应该在应用程序启动时完成一次(或者您可以根据请求动态加载模块 - 在需要时,但可能不是您的情况)。

如果你想在不同的地方使用你的界面的各种实现,你可以使用条件绑定。

条件绑定:

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

或者您可以使用命名NamedAttribute

命名属性:

结合

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

将注入ConsoleWritter的类的构造函数。

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

NamedAttribute的问题在于它会将你绑定到你的商务类中的Ninject,所以如果你需要这么做就很容易切换IOC容器。

然而,如何进行条件绑定还有更多选择。有关详细信息,请参阅此文档 - Contextual binding

答案 1 :(得分:0)

你的第二个问题可以像这样解决

在你的ninject模块中

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

在使用ninject

检索的类中
public class CarPark : IVehicleCarPark
{
   Ctor(IEnumerable<IVehicle> vehicles) {
       // vehicles will be autoresolved
   }
}