10

循環参照を検出するか、型リゾルバをインターセプトしてデバッグ情報を表示するように Unity を構成することはできますか?

相互に依存するいくつかのインターフェイスとクラスを次に示します。

public interface IThing1 { }

public class Thing1 : IThing1
{
    private IThing2 _thing2;

    public Thing1(IThing2 thing2)
    {
        _thing2 = thing2;
    }

}

public interface IThing2 { }

public class Thing2 : IThing2
{
    private IThing1 _thing1;

    public Thing2(IThing1 thing1)
    {
        _thing1 = thing1;
    }
}

ウィンザー城

これら 2 つのタイプが Castle Windsor で構成されている場合、例外がスローされ、循環参照を見つけるためのデバッグ情報が提供されます。

Castle.MicroKernel.CircularDependencyException: Dependency cycle has been detected when trying to resolve component 'CircularIoC.Thing1'.
The resolution tree that resulted in the cycle is the following:
Component 'CircularIoC.Thing1' resolved as dependency of
    component 'CircularIoC.Thing2' resolved as dependency of
    component 'CircularIoC.Thing1' which is the root component being resolved.

団結

Unity がこれらのタイプをそのように解決するように構成されている場合

    private static void ResolveWithUnity()
    {
        var container = new UnityContainer();

        container.RegisterType<IThing1, Thing1>();
        container.RegisterType<IThing2, Thing2>();

        var thing = container.Resolve<IThing1>();

        container.Dispose();
    }

container.Resolve<> を呼び出すと、StackOverflowException が発生します。

これは文書化された動作ですが、さらに有用な情報があると便利です。循環参照に関する詳細情報を提供するカスタマイズはありますか?

または、型リゾルバー プロセスにフックしてデバッグ情報を出力する方法はありますか? メインの型リゾルバーを装飾して、解決中の型の名前を出力することを考えています。これにより、循環参照の原因となっている依存関係へのフィードバックとポインターが提供されます。

別の IoC に変更すると問題が解決することはわかっていますが、残念ながらこれはオプションではありません。

4

1 に答える 1

1

残念ながら、Unity はこの (信じられないほど重要な) 機能をサポートしていません。やり直したいという気持ちがあるなら、ちょっとした手間をかけてスマートなデコレーターを実装することができます。

必要なのは、すべての登録メソッドをオーバーライドし、依存関係 (依存関係グラフ) のデータ構造を構築および更新することです。次に、DFSを実行して循環依存関係を検出するメソッドを作成します。これを登録プロセスのファイナライザーとして使用して、循環依存関係が可能である場合に事前解決を検出するか、要求された特定の型の解決ごとに使用できます。

ご覧のとおり、大変な作業です...

別のオプションは、解決メソッドをデコレータでラップしてStackOverflowExceptionをキャッチし、それを分析して解決プロセスの結果であることを確認し、適切な循環依存例外を構築することです。

于 2014-12-21T12:58:53.687 に答える