1

私は自分のコードでこれを持てるようにしようとしています

@Inject
private Map<String, Provider<Processor>> providers;

私は試していましたが、このコードはコンパイルされません

MapBinder<String, Provider<Processor>> mapbinder = MapBinder.newMapBinder(binder, String.class, Provider<Processor>.class);
mapbinder.addBinding("splineV1Beta").to(SplineProcessor.class);
mapbinder.addBinding("invertV1Beta").to(InvertProcessor.class);

このコードは、マップをバインドできないため、起動時に失敗します

MapBinder<String,Processor> mapbinder = MapBinder.newMapBinder(binder, String.class, Processor.class);
mapbinder.addBinding("splineV1Beta").to(SplineProcessor.class);
mapbinder.addBinding("invertV1Beta").to(InvertProcessor.class);

ここでバインディングを正しくセットアップするにはどうすればよいですか?

注: 私も何か簡単なものを探しているので、開発者は新しいプロセッサを入手するたびに 1 行追加するだけです. TypeLiteral および toProvider() メソッドを使用して、上記に加えて他のことも試しました)。

詳細情報: 以下の行があるかどうかわかりました (ただし、addBinding はまったく呼び出さないでください)

Provider<? extends Provider<Processor>>
//This below line ends up with mabbinder2.addBinder().to() wanting the above param type?
MapBinder<String, Provider<Processor>> mapbinder2 = MapBinder.newMapBinder(binder, stringLit, list);

私の考えを根本的に変えて、私はこのようなものを注入しようとします( map.get("xxx") が毎回新しいインスタンスを作成することを願っています...

@Inject
private Map<String, Processor> providers;

このようにバインドしましたが、残念ながら、マップは常に同じインスタンスを返します:(...

MapBinder<String, Processor> mapbinder = MapBinder.newMapBinder(binder, String.class, Processor.class);
mapbinder.addBinding("splineV1Beta").toProvider(new TypeLiteral<Provider<SplineProcessor>>() {;});
mapbinder.addBinding("invertV1Beta").toProvider(new TypeLiteral<Provider<InvertProcessor>>() {;});

編集: このドキュメントhttp://google-guice.googlecode.com/svn/trunk/latest-javadoc/com/google/inject/multibindings/MapBinder.htmlによると、

 MapBinder<String, Snack> and inject a Map<String, Provider<Snack>>

しかし、(プライベートフィールドを使用して)それを行うと、次のようになります....(一方、他のソリューションに変更してもmapbinder.addBindingを呼び出さないと、バインドされて正常に動作します)...

1) No implementation for java.util.Map<java.lang.String,    
javax.inject.Provider<controllers.modules2.framework.Processor>> was bound.

これが彼らの例のように機能するには、コンストラクター注入を使用する必要がありますか? 私は抽象クラスにいるので、10個のクラスを変更するのは非常に不便です:(。

ありがとう、ディーン

4

2 に答える 2

2

Guice は JSR-330 アノテーションを交換可能に使用することについて非常に優れているように見えますが、マルチバインディングはProvidera 内に型を隠しているMapため、代わりに a を注入することを期待している可能性がありますjava.util.Map<java.lang.String, com.google.inject.Provider<...>>。問題を再現できませんでしたが、試してみて、問題が解決するかどうかを確認してください。

補足: どこのコードでも変更したくない場合は、プロバイダーのプロバイダーをMap<String, javax.inject.Provider<Foo>>、 multibinder-created を受け取るものにハック的にバインドできMap<String, com.google.inject.Provider<Foo>>ます。私が正しく、これが問題である場合はjavax.injectcom.google.injectどこにでも行き来するのではなく、1 か所で修正できます。

于 2013-02-12T16:56:25.147 に答える
0

Map<String, Provider<Processor>>注入ポイントで必要な場合は、バインドする方法は次のとおりです。

MapBinder<String, Processor> mapbinder = MapBinder.newMapBinder(binder, String.class, Processor.class); mapbinder.addBinding("splineV1Beta").to(SplineProcessor.class); mapbinder.addBinding("invertV1Beta").to(InvertProcessor.class);

カスタム プロバイダーを提供している場合に使用toProvider()しますが、これは提供していません。つまり、暗黙的な基になるプロバイダーを使用しようとしているだけです。

于 2015-08-28T22:32:20.240 に答える