2

私は Dependency Injection の初心者であり、Ninject をいじって小さなテスト アプリケーションを作成し、概念を理解しようとしています。Mark Seemann の.NET での Dependency Injection は、私の読書リストの次です。

簡単なテストで遭遇した 1 つの問題は、クラスがその型の新しいインスタンスをインスタンス化できるケースを処理する方法がわからないことです。例として、ボタンのあるフォームがあります。ユーザーがボタンをクリックすると、フォームは同じタイプの別のフォームを作成します。

DI を使用しない場合、上記のシナリオではnew、元のフォームのクリック イベント ハンドラーで別のフォーム インスタンスを作成するだけです。好ましい方法は、抽象ファクトリを使用してインスタンスを作成し、それにクラスを依存させることであると私は理解しています (そして、私はこの分野では素朴かもしれません)。

以下は、私が試したコードです (フォームとは関係なく、単純なクラスのみ)。これは、循環依存関係のために機能しません。なぜそれが発生しているのかがわかります。new手動で何かをする必要のない良い解決策が思い浮かびません。キーピースが欠けているような気がします。

public interface IMainClass
{
    IMainClass CreateNew();
    void Do();
}

public interface IMainClassFactory
{
    IMainClass CreateNew();
}

public class MainClassFactory : IMainClassFactory
{
    private readonly IMainClass _mainClass;

    public MainClassFactory(IMainClass mainClass)
    {
        _mainClass = mainClass;
    }

    public IMainClass CreateNew()
    {
        return _mainClass;
    }
}

public class MainClass : IMainClass
{
    private readonly IMainClassFactory _mainClassFactory;

    public MainClass(IMainClassFactory mainClassFactory)
    {
        _mainClassFactory = mainClassFactory;
    }

    public IMainClass CreateNew()
    {
        return _mainClassFactory.CreateNew();
    }

    public void Do()
    {
        Console.WriteLine("Do from Main Class");
    }
}

public class Program
{
    public static void Main()
    {
        IKernel kernel = new StandardKernel();

        kernel.Bind<IMainClassFactory>().To<MainClassFactory>();
        kernel.Bind<IMainClass>().To<MainClass>();

        var mainClassFactory = kernel.Get<IMainClassFactory>();
        var mainClass = mainClassFactory.CreateNew();

        mainClass.Do();

        Console.WriteLine("Press <ENTER> to exit...");
        Console.ReadLine();
    }
}

このコードが間違っていることはわかっています。

  • IMainClass は IMainClassFactory を実装する必要がありますか? それは問題ですか?
  • kernel.Bind<IMainClass>().To<MainClass>();正しくないようですが、どうすればよいかわかりません
  • 独自のオブジェクトを作成することはnew完全に禁止されていますか?
  • Service Locator アンチパターンを使用しないことについては、かなりよく理解していると思います。クラスに IOC コンテナーを認識させたくありません。

これらのタイプのシナリオは常に発生していると確信しているため、一般的なケースで推奨されるソリューションを探しています。可能であれば、別の実装に移行したい場合に備えて、Ninject 固有のエキゾチックな機能の使用を避けたいと考えています。

編集 1: 'Autofac Circular Component Dependency Detected' エラー 私の読み間違いかもしれませんが、ハリウッド原則に違反しているように見えます

4

1 に答える 1

0

純粋なDIの観点からは、抽象ファクトリが適切な方法ですが、おそらくここでパターンが欠落しています。

ユーザーがボタンをクリックすると、フォームは同じタイプの別のフォームを作成します。

フォームは他のフォームに直接依存しないでください。これはそれらを一緒に配線します。画面ナビゲーションとアプリケーションのフローを処理するための集中化されたポイントが必要です。つまり、不足しているのはアプリケーションコントローラーです。

フォームは、IApplicationControllerまたは類似のものに依存する必要があります。このアプリケーションコントローラーは、新しいフォームを作成する抽象ファクトリに再び依存する可能性があります。

于 2012-10-04T18:40:11.200 に答える