2

2 つのクラスがあるとしますが、それらはファクトリ経由でのみ作成できます。それを強制するために、ファクトリを作成中のオブジェクトの内部クラスにして、プライベート コンストラクタにアクセスできるようにします。この場合、あるクラスは他のクラスのインスタンスを作成する必要があり、2 番目のクラスは最初のクラスのインスタンスを作成する必要があります。

public class A
{
    public class Factory
    {
        private readonly B.Factory bFactory;

        public Factory(B.Factory bFactory)
        {
            this.bFactory = bFactory;
        }

        public A Build()
        {
            return new A(this.bFactory);
        }
    }
    private A(B.Factory bFactory)
    {
    }
}

public class B
{
    public class Factory
    {
        private readonly A.Factory aFactory;

        public Factory(A.Factory aFactory)
        {
            this.aFactory = aFactory;
        }

        public B Build()
        {
            return new B(this.aFactory);
        }
    }
    private B(A.Factory aFactory)
    {
    }
}

通常は、とインスタンスのABFactory両方を作成できるという別のファクトリを作成することでこれを解決し、 との依存関係を両方とも宣言しますが、その場合はとの両方のプライベート コンストラクターにアクセスできません。ABABABFactoryABFactoryAB

Aセマンティクスが正しいと仮定すると (この場合、 an が のインスタンスを返し、それが another のインスタンスをB返すことは論理的に理にかなっています)、これを解決する最善の方法は何ですか?BA

更新 1

これまでの私の解決策は、 a という新しいクラスを作成することCircularDependencyResolverです。2 つのファクトリのそれぞれが、他のファクトリではなく、そのファクトリへの依存関係を宣言します。それぞれthisが、自身のコンストラクターでそのリゾルバーに自身を登録します ( )。それぞれのオブジェクトを構築するときにResolve、リゾルバーでメソッドを呼び出します。これは、他の登録済みファクトリーを探すか、例外をスローします。

もちろん問題は、AorBの依存関係の解決を、プログラムの開始時ではなく、実際に作成する必要があるときまで延期したことですが、それは機能します。

私はまだ他のソリューションに興味があります。

4

2 に答える 2

1

私の推測: セマンティクスは正しくありません。哲学的な方法で、B のインスタンスが存在する場合にのみ A を作成できる場合 (この場合、従来の構造と比較して、ファクトリ パターンの関連性はわかりません。問題をコードごとに移動するだけなので、意味的にはそうではありません)、B は A が存在する場合にのみ作成できます。その場合、両方が存在しない限り、両方を作成することはできません。

A と B が同じものの一部であることを除いて、他なしで作成できる 1 つが存在する必要があります (B は A の独自のインスタンスを作成する必要があるため)。一方を他方のプロパティにする必要があります。

おそらく、セマンティクスを明確にするために、OOPの​​約と構成の概念の違いを確認すると役立つでしょう。

ちなみに、インスタンスを作成することはできないため、依存性注入のコンテキストで見ているかどうかは問題ではありません。

かもしれませんが、何かが足りないのです... 興味深い質問です!

編集:

では、これはどうでしょうか。

public class A
{
    private int _privateInt;

    private B CreateB()
    {
        return B.Factory.Build();
    }

    public static class Factory
    {
        public static A Build()
        {
            return new A {_privateInt = 1};
        }
    }

    private A()
    {
    }
}

public class B
{
    public static class Factory
    {
        public static B Build()
        {
            return new B();
        }
    }

    private B()
    {
    }
}

でも、多分、私は本当に問題を理解していませんか?

編集2:

あなたのシナリオを実際に想像することはできませんが、特に DI のコンテキストで、あるクラスのファクトリを別のクラスに渡す必要があるのはなぜですか? あるクラス (たとえば B) の新しいインスタンスを別のクラス (A) から取得したい場合、コンテナにそのインスタンスを作成させてみませんか?

編集3:

コンテナーがLazyインスタンスのイニシャライザーの解決をサポートしている場合は、それらをコンストラクター パラメーターの型として使用できます。

public A(Lazy>B> b) {}
于 2013-03-08T16:47:38.777 に答える
0

まず第一に、@PeterRitchieが彼のコメントで言ったことにもちろん同意します。循環依存関係は強力な設計の匂いであり、次に循環依存関係を壊すために、Marc Seemannの本Dependency Inject in .NETで読んだアドバイスに従います。それは次のとおりです。

イベントを使用してサイクルに対処しようとします。それが失敗した場合は、オブザーバーを試してください。それでもうまくいかない場合にのみ、PROPERTY INJECTION を使用して悪循環を断ち切ることを検討してください。

これがすべて失敗した場合は、オブジェクト指向言語で有名な解決策を使用します。これは、別の依存関係または抽象化を導入して、実際に行ったことであるサイクルを断ち切ることです。

于 2013-03-09T23:56:42.643 に答える