Java inject implementation using TypeLiteral

我与影子孤独终老i 提交于 2019-12-24 00:46:02

问题


I have a project that provides an interface, let's call it IImplementMe, which i want to inject into my project. This interface will be implemented by various producers, so I need to inject all implementations. I am trying to use TypeLiteral for this.

Here is the code of the producer :

@Singleton
public class SomeImplementation implements IImplementMe {

private final String value;

@Inject
public SomeImplementation(final SomeOtherConfig configuration) {
    this.value= configuration.getValue();
}

@Override
public String getValue() {
    return value;
}
}

And in my registry class I have register(IImplementMe.class).to(SomeImplementation.class);

Then, in my project I inject it like this :

@Inject
public SomeEndpoint(final List<IImplementMe> implementations){
///
}

and i bind it like

private static class MarketDataSetTypeLiteral extends TypeLiteral<List<IImplementMe>> {
}
bind(new MarketDataSetTypeLiteral()).toRegistry();

I made sure my SomeIMplementation constructor gets called, but in my endpoint the List is empty, so no implementation is provided. I'm using guice for injection. Any ideas ?

LE: It turns out that the provided implementation is created after my endpoint class is created (at creation time it injects a reference of an empty list). Later in the lifecycle the reference is updated with the implementation, so I actually have access to it after guice does it's stuff.

I'm guessing it's due to the maven dependencies, and how guice handles the instantiations. Since the producer must have a dependency on my project, I guess it makes sense it gets instantiated last, thus causing my initial problem.


回答1:


You are looking for multibindings -> https://github.com/google/guice/wiki/Multibindings

public class IImplementMeModule extends AbstractModule {
  public void configure() {
    Multibinder< IImplementMe > uriBinder = Multibinder.newSetBinder(binder(), IImplementMe.class);
    uriBinder.addBinding().to(SomeImplementationOfIImplementMe.class);
    uriBinder.addBinding().to(AnotherImplementationOfIImplementMe.class);

    ... // bind plugin dependencies, such as our Flickr API key
  }
}

Then you can inject the set of IImplemetnMe as following

@Inject TweetPrettifier(Set<IImplemetnMe> implementations)

I would suggest you to have a look at MapBindings which allows you provide keys for each implementation and then you will be able to inject your bindings as a Map



来源:https://stackoverflow.com/questions/36690178/java-inject-implementation-using-typeliteral

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