3

私のJavaコードは、インターフェースの複数の実装(以下の例ではBugTemplate)を使用しており、バインドされた実装はコンテキストに依存します。

Guiceでは、これを実現する適切な方法はBindingAnnotationsを使用することだと思います。ただし、私のユースケースは、コンテキストがインターフェイスの実装から1レベル削除されているという点で、標準的な例とは異なります。

考えられる依存関係の要約:

FooBugFinder-> BugFiler-> FooBugTemplate

BarBugFinder-> BugFiler-> BarBugTemplate

コード例:

class FooBugFinder {
  // ...
  public findBugsAndFileThem() {
    List<Bug> bugs = findBugs();
    bugFiler.fileBugs(bugs);
  }
  @Inject
  FooBugFinder(BugFiler bugFiler) {
    // BugFiler should have been instantiated with a FooBugTemplate.
    this.bugFiler = bugFiler;
  }
}

class BugFiler {
  // ...
  public fileBugs(List<Bug> bugs) {
    List<FormattedBugReport> bugReports = bugTemplate.formatBugs(bugs);
    fileBugReports(bugReports);
  }
  @Inject
  BugFiler(BugTemplate bugTemplate) {
    // The specific implementation of BugTemplate is context-dependent.
    this.bugTemplate = bugTemplate;
  }
}

interface BugTemplate {
  List<FormattedBugReport> formatBugs(List<Bug> bugs);
}

class FooBugTemplate implements BugTemplate {
  @Overrides
  List<FormattedBugReport> formatBugs(List<Bug> bugs) {
    // ...
  }
}

私の最初の考えは、ctorに次のように注釈を付けることです。

FooBugFinder(@Foo BugFiler bugFiler) { }

ただし、Guiceは、BugFilerのコンストラクターに引数を挿入するときに、そのアノテーションを適用することをどのように知るのでしょうか。

つまり、FooBugFinderには、FooBugTemplateでインスタンス化されたBugFilerインスタンスが必要です。BarBugFinderには、BarBugTemplateでインスタンス化されたBugFilerインスタンスが必要です。

何か案は?

4

1 に答える 1

1

BugFilerこれを行うには、注釈付きオブジェクトを公開するプライベートモジュールを作成します。

abstract class BugFilerModule extends PrivateModule {
  private final Class<? extends Annotation> annotation;

  BugFilerModule(Class<? extends Annotation> annotation) {
    this.annotation = annotation;
  }

  @Override protected void configure() {
    bind(BugFiler.class).annotatedWith(annotation).to(BugFiler.class);
    expose(BugFiler.class).annotatedWith(annotation);
    bindBugTemplate();
  }

  abstract void bindBugTemplate();
}

次に、インジェクターを作成するとき:

    Injector injector = Guice.createInjector(
        new BugFilerModule(Foo.class) {
          @Override void bindBugTemplate() {
            bind(BugTemplate.class).to(FooBugTemplate.class);
          }
        },
        new BugFilerModule(Bar.class) {
          @Override void bindBugTemplate() {
            bind(BugTemplate.class).to(BarBugTemplate.class);
          }
        },
        /* other modules */);

FooBugFinderそして、あなたはあなたが提案する方法でを作成することができます:

public class FooBugFinder {
  @Inject
  public FooBugFinder(@Foo BugFiler fooBugFiler) {
    ...
  }
}
于 2013-03-12T21:33:56.583 に答える