質問

この単純な例を考えてみましょう。

Class A {
   B b;
   A() {
       this.b = new B(this);
   }
}

この例の場合においてAは、インスタンスBを知っている、およびインスタンスBは、インスタンスAを知っている。

私の質問は次のとおりです。のGuiceのでインスタンスAをインスタンス化する方法、すなわち、どのようにGuiceのは、この複雑なサークルの依存関係の世話を作るために、

役に立ちましたか?

解決

あなたは、単にコンストラクタに@Injectを追加することができます:

このあなたの最初の質問「どのようにGuiceのでインスタンスAをインスタンス化する」を答えるために

class A {
   private final B b;

   @Inject
   A() {
       this.b = new B(this);
   }
}
Aを作成するためのAPIは、円形の依存関係を持っていないため、

この作品。 Guiceのは、ちょうどAコンストラクタにそれがAオブジェクトを作成したり、注入する必要があるすべての時間を使用します。

あなたの質問は、<のhref = "http://misko.hevery.com/2008/08/01/circular参照、オブジェクトを作成するためのAPIは、循環依存関係を持つオブジェクトを作成するために、Guiceのを使用する方法である場合-dependency・イン・コンストラクタ-と依存性注入/」のrel = "nofollowをnoreferrer"> Misko Hevery の(ユーリの答えで述べたように)。することによって、このブログの記事

他のヒント

あなたが直接Bを構築しているので、

あなたの例では、まったく問題ではありません。あなたはGuiceのによって作成されるようにAとBの両方にしたい場合はしかし、一方または両方のインターフェイスでなければなりません。あなたが行うことができます:

public interface A { /* skipping methods */ }
public interface B { /* skipping methods */ }

public class AImpl implements A {
   private final B b;

   @Inject
   public AImpl(B b) {
      this.b = b;
   }
   // ...
}

public class BImpl implements B {
   private final A a;

   @Inject
   public BImpl(A a) {
      this.a = a;
   }
   // ...
}

AImplBImplがシングルトンとしてスコープされている場合でも、Guiceのは、(プロキシを介して)この注入を扱うことができます。これは私がそれを扱うことができなかった、より複雑な循環依存関係があるかもしれないと想像...いずれにせよ、このような単純なケースで動作します。とにかく、円形の依存性を排除することはもちろん、好ましいであろう。

答えはあなたのコードでの円形の依存関係を持っていながら、を使用すると、依存性注入フレームワークを使うべきではないということです。

だから、あなたは予めごコードをリファクタリングする必要があります。詳細ルック<のhref = "http://misko.hevery.com/のための1に2つのクラスをマージしたり、新しいクラスを導入し、その中に共通のロジックを動かすのいずれか(:私の知る限りでは、密結合のクラスには2つのソリューションがあります2008/8月1日/円形依存型コンストラクタアンド依存性注入/」REL = 『nofollowをnoreferrer』>こちら)

私はNamshubWriterの提案は非常にguicyではないと思われます。フィールドにパラメータを割り当てる:私はGuiceの中で、コンストラクタは正確に一つのことを行うべきだと思います。あなたがする必要がある何かがある場合、工場またはプロバイダにそれを置きます。

この場合、我々はA.のプロバイダをプロバイダが直接新しいBを呼び出すことができます()、しかし、我々は、我々は最初の場所で避けることを試みたものですBに直接カップルAと思いたくなるでしょう。 GuiceのはassistedInjectを経由して私たちのために提供することができ、工場、オーバーBのだから我々は間接的な創造。このコードは、実行され、微細なコンパイル、および完全に切り離さAとB

現実的なシナリオでは、あなたは分離を利用するインタフェースの後ろにAとBを非表示にする必要があると思います。

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.FactoryProvider;

public class Try {
    public static void main(String[] args) {
        System.out.println(
                Guice.createInjector(new MyModule()).getInstance(A.class)
        );
    }
}

class MyModule extends AbstractModule {
    public void configure() {
        bind(A.class).toProvider(AProvider.class);
        bind(IBFactory.class).toProvider(
                FactoryProvider.newFactory(IBFactory.class, B.class));
    }
}

class A {
    B b;

    public void setB(B b) {
        this.b = b;     
    }
}

class B {
    A a;

    @Inject
    B(@Assisted A a) {
        this.a = a;
    }
}

class AProvider implements Provider<A> {

    private final IBFactory bFactory;

    @Inject
    AProvider(IBFactory bFactory) {
        this.bFactory = bFactory;
    }

    public A get() {
        A a = new A();
        a.setB(bFactory.create(a));
        return a;
    }
}

interface IBFactory {
    public B create(A a);
}

Iは円形の依存性注入の拡張バージョンを作っGuiceの中でAとBは、インターフェースの背後に隠されている。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top