2013-01-10 36 views
0

我已经从下面的链接中参考了本示例。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");} 
} 

现在在我的主程序中,我会有这样的东西。在这里,我使用新的操作员来创建汽车,公共汽车和卡车的三个具体实现。我必须显示所有三辆车的规格。现在我想知道如何编写我的Ninject代码,以便不存在具体类的依赖关系。

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

回答

2

模块安装应该再对应用程序启动来完成(或者你可以动态地加载模块,每个请求 - 在需要的时候,但它不是可能是你的情况下)。

如果你想在不同的地方使用不同的接口实现,你可以使用条件绑定。

条件结合:

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

或者你可以使用命名NamedAttribute

命名属性:

绑定

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

类的构造函数,其中ConsoleWritter将被注入。

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

问题与NamedAttribute是,它会配合你Ninject在bussines类,所以如果你需要的话就不会有问题,容易切换IOC容器。

但是,如何进行条件绑定还有更多的选择。请参阅此文档以获取更多信息 - Contextual binding

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 
    } 
} 
检索类