0

I have taken the reference of this example from the link below.

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

}
}

In the Load() method, ConsoleWriter is being wired up with IWriter. It looks static and hardcoded. i.e. every time I call IWriter, it will initialize ConsoleWriter. What if I want to use MessageBoxWriter as well. I will have to change the code in Load() method to achieve that. Am I missing anything or it is how Ninject behaves?

Furthermore, Load() method will be called by all types of wiring up. In some other class, I might need to wire ConsoleReader with IReader. In that case, the same

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

will also be hit. Is this the expected way of Ninject?

Let me explain my question in more details. Lets say I have an interface given below.

public interface IVehicle
{
 PrintSpecification();
}

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

2 に答える 2

2

モジュールのロードは、アプリケーションの起動時に 1 回実行する必要があります (または、要求ごとに動的にモジュールをロードすることができます - 必要な場合ですが、おそらくあなたのケースではありません)。

さまざまな場所でインターフェイスのさまざまな実装を使用する場合は、条件付きバインディングを使用できます。

条件付きバインディング:

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

または、ネーミングとを使用できますNamedAttribute

名前付き属性:

バインディング

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

ConsoleWritter注入されるクラスのコンストラクター。

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

問題NamedAttributeは、bussines クラスで Ninject に結び付けられることです。そのため、必要に応じて IOC コンテナーを簡単に切り替えるには問題があります。

ただし、条件付きバインディングを行う方法は他にもあります。詳細については、このドキュメントを参照してください - Contextual binding

于 2013-01-10T11:57:51.710 に答える
0

あなたの2番目の質問はこのように解決することができます

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
   }
}
于 2013-01-12T00:31:10.410 に答える