3

Ninject コンストラクター インジェクションを使用して、クラスとその依存関係をインスタンス化するために呼び出すことができるジェネリック ファクトリを作成しようとしています。うまく機能しているようですが、うまくいきません。ジェネリックと IoC コンテナーを初めて使用したためかどうかはわかりませんが、私のアプローチには欠陥があると思います。悪く説明するのではなく、単純なテスト コンソール アプリをダンプします。

Farm.cs

class Farm
{
    private readonly IAnimal _animal;
    private readonly IVehicle _vehicle;

    public Farm(IAnimal animal, IVehicle vehicle)
    {
        _animal = animal;
        _vehicle = vehicle;
    }

    public void Listen()
    {
        _animal.Speak();
        _vehicle.Run();
    }
}

program.cs

class Program
{
    static void Main(string[] args)
    {
        var farm = new NinjectFactory<Farm>().GetInstance();

        farm.Listen();

        Console.Read();
    }
}

NinjectFactory.cs

class NinjectFactory<T>
{
    public T GetInstance()
    {
        var kernel = new StandardKernel(new IoCModule());

        return kernel.Get<T>();
    }
}

NinjectModule.cs

class IoCModule : NinjectModule 
{
    public override void Load()
    {
        Bind<IAnimal>().To<Dog>();
        Bind<IVehicle>().To<Tractor>();
    }
}

アイデアやフィードバックをいただければ幸いです。

4

1 に答える 1

2

Ninject コンストラクター インジェクションを使用して、クラスとその依存関係をインスタンス化するために呼び出すことができるジェネリック ファクトリを作成しようとしています。

Ninject Kernel(またはそのことについては任意のコンテナー) はジェネリック ファクトリです。そのジェネリック ファクトリをジェネリック ファクトリの背後に隠しています。これを簡単に行うことができます:

private static StandardKernel kernel;

static void Main(string[] args)
{
    Bootstrap();

    // Resolve the application's root type
    // by using the container directly.
    var farm = kernel.Get<Farm>();

    // Operate on the root type
    farm.Listen();

    Console.Read();
}

private static Kernel Bootstrap()
{
    kernel = new StandardKernel();

    kernel.Bind<IAnimal>().To<Dog>();
    kernel.Bind<IVehicle>().To<Tractor>();
    kernel.Bind<Farm>().ToSelf();
}

ジェネリック ファクトリを使用してコンテナをアプリケーションから隠すことを考えている場合、これは、アプリケーション コードがその静的ファクトリに依存していることを意味します。これは大したことではありません。すべての型はコンストラクター注入を中心に設計する必要があり、ジェネリック ファクトリを注入することは、カーネル自体を型に注入することと同じです。これにより、コードの保守、テスト、検証が困難になります。

于 2012-10-11T21:33:15.633 に答える