web-dev-qa-db-ja.com

ダガー:@名前付き文字列を注入しますか?

[〜#〜] edit [〜#〜]2018-02-08:これを行う方法を示すサンプルプロジェクト https:/ /github.com/ravn/dagger2-named-string-inject-example -注: ソース全体が単一のファイルにあります


ダガーが私たちのためにguiceを置き換えることができるかどうかを見ています(私たちの展開Javaプラットフォームが遅いため)]。

実行時に構成文字列のマップを作成し、必要に応じて短剣を挿入します。

例えば。私が持っている場合

Java.util.Map<String, String> map = new Java.util.TreeMap<String, String>();
map.put("key", "value");

そして

@Inject
Thermosiphon(Heater heater, @Named("key") String value) {
    this.heater = heater;
    System.out.println("value =" + value);
}

バリューに「バリュー」を注入したいのですが。

ソースコードの例には、@ Namedの使用法はありません。試行するだけで次の例外が発生します。

Exception in thread "main" Java.lang.IllegalStateException: Errors creating object graph:
  No binding for @javax.inject.Named(value=key)/Java.lang.String required by class bar.Thermosiphon
    at dagger.internal.ThrowingErrorHandler.handleErrors(ThrowingErrorHandler.Java:34)
    at dagger.internal.Linker.linkRequested(Linker.Java:146)
    at dagger.ObjectGraph$DaggerObjectGraph.getInjectableTypeBinding(ObjectGraph.Java:288)
    at dagger.ObjectGraph$DaggerObjectGraph.get(ObjectGraph.Java:249)
    at app.CoffeeApp.main(CoffeeApp.Java:20)

私はこれにどのように取り組むべきですか?

マップがあり、これらを自動的に名前付き文字列にバインドするものを使用したいようです。 Guaggerではプロパティバインダーを作成できるため、Duaggerでは、Guiceのように自動的にそれを行うことはできません。

Daggerは、すべてのバインディングと依存関係が確実に満たされるように分析を行うために、コンパイル時にすべてのバインディングの知識を必要とします

とは言っても、このようなことをすることができます-それはより定型的なものですが、合法です。

@Module(library = true)
public class PropertiesModule {
  public final Properties props;

  PropertiesModule(Properties props) {
    this.props = props;
  }

  @Provides @Named("property.one") String providePropertyOne() {
    props.getProperty("property.one", "some default");
  }

  @Provides @Named("property.two") String providePropertyTwo() {
    props.getProperty("property.two", "some other default");
  }
  ...
}

これにより、作成する必要があるすべてのバインディングを実行時の値で満たすことができます。ただし、キーはコンパイル時に既知です(そして、コードで@Named( "string literal")を使用しているため、既知である必要があります)。プロパティ名とデフォルトを定数文字列として定義している場合は、行う:

  @Provides @Named(PROPERTY_NAME_CONSTANT) String a() {
    props.getProperty(PROPERTY_NAME_CONSTANT, PROPERTY_NAME_CONSTANT_DEFAULT);
  }

それはより多くのボイラープレートですが、Daggerは、ボイラープレートの多くを排除する一方で、ボイラープレートの絶対的な削減よりもコンパイル時の分析を優先しています。そうは言っても、この状況を改善し、既知のリストなどからシステムプロパティのモジュールを自動生成する機能を提案します。このボイラープレートでも削減できると思います。

19

@Namedインスタンスのdaggerモジュールでプロバイダーを定義する必要があります。

@Provides @Named("foo") String provideFoo()
{
    return "foo string";
}

次に、コンストラクターで名前付きインスタンスを注入するか、依存クラスでフィールド注入を使用できます。

public class Thermosiphon
{
    @Inject @Named("foo") String fooString;

    @Inject public Thermosiphon(Heater heater)
    {
        System.out.println("value of fooString is " + fooString);
    }
}
16
jfrey