2

これは、Unityのバグを示しているように見えるコンソール アプリケーションの例です (Unity NugGet パッケージを追加すると正常に動作します) 。

using System;
using Microsoft.Practices.Unity;

class GC { public static UnityContainer Container = new UnityContainer();}

class Program
{
    static void Main(string[] args)
    {
        GC.Container.RegisterType<MyView>();
        var myView = GC.Container.Resolve<MyView>();
        Console.ReadLine();
    }
}

public class MyClassDesign: MyClass{}
public class MyClass: VMBase<MyClass, MyClassDesign>{}
public abstract class VMBase<TViewModel, TDesignVM> where TDesignVM:TViewModel
{
    static VMBase()
    {
        if (!GC.Container.IsRegistered(typeof(TViewModel)))
            GC.Container.RegisterType(typeof (TViewModel), typeof(TDesignVM));
    }
}

public class MyView
{
    public MyView(MyClass myClass)
    {
        Console.WriteLine("Bad: "+myClass.GetType().ToString());
        Console.WriteLine("Good: "+GC.Container.Resolve<MyClass>().GetType());
    }
}

出力は次のとおりです。

悪い: MyClass
良い: MyClassDesign

解決された型はMyClass. しかし、そうあるべきですMyClassDesign。(静的コンストラクターは、クラスで MyClass が解決される前に実行されMyViewます。)

Unity で静的コンストラクターでマッピングをセットアップできるようにするにはどうすればよいですか?

注: UnityContainer の設定を (コードではなく) ファイルで変更すると、すべて正常に動作します。しかし、私はこれを外部ファイルに依存したくありません。(あまり多くの依存関係を持たせたくない再利用可能なテンプレートを作成しています。)

4

2 に答える 2

0

ビューモデル内に登録ロジックを配置したいのはなぜですか?これにより、アプリケーションコードがコンテナに結合されますが、これは決して良い考えではありません。コンポジションルーツの概念を見てください。

DIコンテナのすべてのセットアップコードをそこに配置する必要があります。

于 2012-06-07T07:04:58.510 に答える
0

これは実際には Unity のバグではありません。問題は、インスタンスが要求されるまで静的 ctor が実行されないことです (その時点ではまだ unity は不明ですMyClassDesign)。これは、Unity がMyClass要求を満たすために のインスタンスの作成を既に開始していることを意味します。後続の への呼び出しはGC.Container.Resolve<MyView>();、期待どおりの出力になります。Sebastian Weber が示唆しているように、すべてのセットアップ コードを完全に別の場所に配置する (クラスが特定の DI コンテナーに依存しないようにする) ことが最善の選択肢です。

于 2012-06-07T07:25:09.067 に答える