3

クラスのデフォルトの impl があり、それが @Inject コンストラクターを定義している場合、それは素晴らしいことです。システムがそれを拾います。

1 つのアプリがそのデフォルトの impl をサブクラスでオーバーライドしたい場合、そのモジュールで @Provides を定義し、独自のコードでそのサブクラスで「new」を呼び出すことができ、dagger は代わりにその impl を使用します (これまでのところ、私が知る限り、これは機能します)。

ただし、短剣でそのサブクラスをインスタンス化する場合、@Module で「override=true」を宣言せずに実行する方法はありますか? ビルド時のすべての重複チェックで適切な警告が表示されるように、override=true を使用しないのが好きです。

もちろん、それを行う 1 つの方法は、すべてのアプリに @Provides を直接宣言させることです。それは膨満感を増すだけです。

私は以前に GIN (Guice for GWT) を使用したことがあり、.class 参照によって必要なクラスへのバインディングを定義できますが、短剣に似たものは見当たりません。

4

1 に答える 1

3

現在のところ、"overrides" 属性を使用せずに自由にオーバーライドできる "デフォルト バインディング" を持つ方法はありません (これは、これよりもテストを目的としていました)。デフォルト バインディングを行う方法を検討しています。

これらの行に沿って次のようなものを用意することで、これを行うために set バインディングを使用することを検討できます。

@Module(...)
class MyModule {
  @Qualifier @interface OverridableFoo { }

  @Provides(type=SET_VALUES) @OverridableFoo Set<Foo> provideOverriddenFoo() {
    return new HashSet<Foo>(); // Empty set to ensure the Set is initialized.
  }

  @Provides Foo provideFoo(@OverridableFoo Set<Foo> Foo overriddenFoo) {
    switch (overriddenFoo.size()) {
      case 0: return new DefaultFooImpl();
      case 1: return overriddenFoo.iterator().next();
      default: throw new IllegalStateException("More than one overridden Foo Provided.");
    }
  }
}

次に、オーバーライドする場合は、これを含めるだけです。

@Module(...)
class MyModule {
  @Provides(type=SET_VALUE) @OverridableFoo Foo provideBetterFoo() {
    return new MyAwesomeFoo();
  }
}

これは、コンパイル時エラーであるべきものを実行時に移動するため、良い方法ではありませんが、デフォルトのバインディングを処理する方法を決定しようとする間の応急処置として、実行可能だと思います.

于 2013-08-25T19:07:18.840 に答える