5

私は Guice のドキュメントを読んでいて、「サイクルを排除する (推奨)」というラベルの付いたセクションに出くわしました。これは、まさに今日ドキュメントにたどり着いた問題であるため、私の関心のピークに達しました。

基本的に、循環依存を排除​​するには、「依存ケースを別のクラスに抽出」します。わかりました、新しいことは何もありません。

したがって、この例では次のようになります。

public class Store {
        private final Boss boss;
        private final CustomerLine line;
        //...

        @Inject public Store(Boss boss, CustomerLine line) {
                this.boss = boss; 
                this.line = line;
                //...
        }

        public void incomingCustomer(Customer customer) { line.add(customer); } 
}

public class Boss {
        private final Clerk clerk;
        @Inject public Boss(Clerk clerk) {
                this.clerk = clerk;
        }
}

public class Clerk {
        private final CustomerLine line;

        @Inject Clerk(CustomerLine line) {
                this.line = line;
        }

        void doSale() {
                Customer sucker = line.getNextCustomer();
                //...
        }
}

aStoreと a がClerkあり、それぞれに の単一インスタンスへの参照が必要ですCustomerLine。この概念に問題はなく、従来の Dependency Injection で簡単に実行できます。

CustomerLine customerLine = new CustomerLine();
Clerk clerk = new Clerk(customerLine);
Boss boss = new Boss(clerk);
Store store = new Store(boss, customerLine);

これは簡単ですが、ここでは、Guice インジェクションを使用してこれを行う必要があります。したがって、私の問題は次の実装にあります。

Store と Clerk の両方が同じ CustomerLine インスタンスを使用していることを確認したい場合があります。

はい、それはまさに私がやりたいことです。しかし、Guice モジュールでそれを行うにはどうすればよいでしょうか?

public class MyModule extends AbstractModule implements Module {
    @Override
    protected void configure() {
        //Side Question: Do I need to do this if there if Boss.class is the implementation?
        bind(Boss.class);
        bind(CustomerLine.class).to(DefaultCustomerLine.class); //impl
    }
}

モジュールでインジェクターを作成します。

Injector injector = Guice.createInjector(new MyModule());

今、私はのインスタンスが欲しいStore

Store store = injector.getInstance(Store.class);

これにより、 の新しいインスタンスCustomerLineとが のBossこのインスタンスに挿入されますStoreBossただし、 は のインスタンスを取得し、 のインスタンスClerkも注入されますCustomerLine。この時点で、これは に注入されたインスタンスとは異なる新しいインスタンスになりますStore

質問の再検討

  • を使用せずに、このシーケンスで同じインスタンスStoreを共有するにはどうすればよいですか?Clerk@Singleton

さらに情報が必要な場合、またはこの質問が十分に明確に述べられていない場合はお知らせください。必ず修正します。

4

1 に答える 1

12

プロバイダーを使用する必要があります

public class StoreProvider implements Provider<Store> {
  @Inject 
  private Boss boss ;

  public Store get() {
    return new Store(boss, boss.getClerk().getCustomerLine());
  }
}

そして、それをモジュールにバインドします

bind(Store.class).toProvider(StoreProvider.class);

于 2013-08-21T13:13:41.193 に答える