Question

I know my title is confusing. Im having a hard time to summarize what I want to ask. What I mean is is there a way to use guice to inject classes that implement interface A using a binding method where the annotation is in the class that implements interface A rather than binding it in the configure method or adding a @ImplementedBy annotation in interface A.

Update

As I read tutorials using guice, in order to dictate that a certain class implements an interface one must use bindings. Now there are many ways to perform bindings. Examples of which are: Linked Binding:

bind(AInterface).to(Bclass); 

This code will be located in the configure method of the class that extends abstract module. This tells guice that if their are dependencies that require AInterface it may inject BClass to handle to dependency.

Just in time binding:

@ImplementedBy(BClass.class)
public interface AInterface {
}

This example is equivalent to the linked binding example.

Now all of the bindings I read require me to declare in either the configure method or interface that a class implements that interface. This will require me to edit existing code every time I implement the interface. What I want is to simply have the class that implements the interface handle the binding itself so as not to modify existing code.

Something like

@Exports(AInterface.class)
public BClass implements AInterface{
}
Was it helpful?

Solution

There's no way to do this.

As RC noted in the comments, if you have two classes that both "@Exports" the same interface, Guice wouldn't know which one to pick. Furthermore, consider it from the class-loading perspective:

  • Explicit bindings (either linked or untargeted) work because the Module explicitly refers to every class it binds, which allows Guice to find those classes.
  • JIT bindings work because they ask for the specific class they implement, which also allows Guice to find those classes.
  • @ImplementedBy annotations work because once the class requested has been loaded, it points to the implementation, so Guice knows how to find that class.

If one were to write an @Exports annotation, Guice would effectively have to have already found BClass in order to recognize that it offers AInterface, despite no explicit reference to BClass anywhere. Though class-path scanning solutions exist, they have to mill through every class on the classpath, which takes some time and would be a dangerous thing for Guice to do silently. Therefore, it makes the most sense to require some kind of explicit binding for the case you're looking for.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top