4

Unity DI コンテナーは、最初は Windows フォーム アプリケーションで動作しています。私はProgram.cs次のものを持っています:

static void Main()
{
    var container = BuildUnityContainer();
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(container.Resolve<MainForm>());
}

private static IUnityContainer BuildUnityContainer()
{
    var container = new UnityContainer();
    container.RegisterType<ITest, MyTestClass>();
    container.RegisterType<ISomeOtherTest, MyOtherClass>();
    return container;
}

私のMainFormコンストラクターには、次の機能があります。

private readonly ITest test;

        public MainForm(ITest test)
        {
            this.test = test;
            InitializeComponent();
        }

コンテナーは解決され、コードは正常に動作します。問題/質問は、次のコンストラクターがあるMainFormと言う、から新しいフォームをインスタンス化する方法です。Form2

private readonly ISomeOtherTest someOtherTest;

    public Form2(ISomeOtherTest someOtherTest)
    {
       this.someOtherTest = someOtherTest;
       InitializeComponent();
    }

私ので次のことを試してみるとMainForm

Form2 form2 = new Form2();
form2.Show();

コンストラクターに値を提供していないと不平を言って、壊れます。ただし、コンテナーは既に解決済みであり、下流のコンテナーはすべて解決されると考えていました。明らかに、機能しないため、ここで何かが欠けています。

これは、そのフォームがそれを使用しない場合でも、すべての依存関係をフロントロードする必要があることを意味するので、作成した新しいフォームのインスタンス化にそれらを渡すことができますか? MainForm50 の依存関係を解決する必要があり、最上位フォームのコンストラクターがそれらすべてを取得する場合、これは奇妙になります。Unity と DI コンテナーを Web API と MVC でほぼ独占的に使用しており、コントローラー用に DI リゾルバーが既に組み込まれているため、理解を深めてください。

4

1 に答える 1

6

そのようにフォームを作成する必要があります

Form2 form = container.Resolve<Form2>();

コンテナを使用していないため、フォームには引数を取らないコンストラクタがありません。コンテナーで解決すると、コンストラクターが調べられ、依存関係が検出され、それらがコンストラクターに自動的に挿入されます。

だから..多分あなたの問題は、MainFormのコンテナにアクセスできないことですか? これが問題である場合、2 つのアプローチがあります。

IUnityContainer を MainForm コンストラクターに挿入する

ただし...「構成ルート」パターンに従っている人は、アプリケーションのルートからのみコンテナーを使用する必要があると言うでしょう (この場合、おそらく Main() ) 他のオプションは...

MainForm に注入されるコンポジション ルート (Main) から Form2 ファクトリ クラスを作成し、MainForm はファクトリを使用して Form2 を作成します。

思考の合成ルート理論をもっと読むべきです...

構成ルート


アップデート

以前はそうする必要はありませんでしたが、2番目の方法は次のようになると思います...

public class Form2Factory : IForm2Factory
{
    private readonly ISomeOtherTest someOtherTest;

    public Form2Factory(ISomeOtherTest someOtherTest)
    {
        this.someOtherTest = someOtherTest;
    }

    public Form2 Create()
    {
        return new Form2(someOtherTest);
    }
}


public class MainForm
{
    private readonly IForm2Factory form2Factory;

    public MainForm(IForm2Factory form2Factory)
    {
        this.form2Factory = form2Factory;
    }

    private void DoingSomething()
    {
        Form2 form = form2Factory.Create();
        form.Show();
    }
}
于 2013-07-02T21:58:31.177 に答える