guice multibinder with Providers

元气小坏坏 提交于 2019-12-03 22:51:17

问题


I am trying to be able to have this in my code

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

I was trying but this code does not compile

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);

This code fails on startup in that it can't bind my Map

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

How do I setup the bindings correctly here?

NOTE: I am looking for something easy too so developers just add one line every time we have a new processor.(I am hoping I don't have to add one line + some factory interface...should be a way, but I have tried other things in addition to above with TypeLiteral and toProvider() method as well).

MORE INFO: okay, I found out if I have the below line(but do not call addBinding at all) Guice will actually startup which is good, but all the addBinding().to method signatures are now wrong as they want a

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);

RADICALLY change my thinking and I try injecting something like this(hoping that map.get("xxx") creates new instances every time...

@Inject
private Map<String, Processor> providers;

and I bound it like this but unfortunately, the map is always returning the same instance :(...

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>>() {;});

EDIT: according to this doc http://google-guice.googlecode.com/svn/trunk/latest-javadoc/com/google/inject/multibindings/MapBinder.html you can have a

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

but when I do that(with a private field), I get the following....(whereas when I change to my other solution but don't call mapbinder.addBinding, it binds and works just fine)...

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

Do I have to use constructor injection for this to work like their example? I am in an abstract class so that would be very inconvenient to change 10 classes :(.

thanks, Dean


回答1:


Though Guice seems to be very good about using JSR-330 annotations interchangeably, it seems that Multibindings hides the Provider type within a Map and therefore may be expecting to inject a java.util.Map<java.lang.String, com.google.inject.Provider<...>> instead. I haven't been able to reproduce your problem, but try that and see if it helps.

Side note: If you want to avoid changing it in code everywhere, you can hackishly bind a provider of Map<String, javax.inject.Provider<Foo>> to something that takes in the multibinder-created Map<String, com.google.inject.Provider<Foo>>. If I'm right and this is the problem, you can fix it one place rather than bouncing between javax.inject and com.google.inject everywhere.




回答2:


If you want Map<String, Provider<Processor>> at the injection point, the way to bind it is:

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

You would use toProvider() if you are supplying a custom provider, which you are not, i.e. you are merely trying to use the implicit underlying provider.



来源:https://stackoverflow.com/questions/14833777/guice-multibinder-with-providers

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!