我从下面的链接中引用了这个例子。
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()
方法。在其他一些课程中,我可能需要将ConsoleReader
与IReader
联系起来。在那种情况下,相同的
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();
}
答案 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
}
}