Say I have a Module structure like this:
Root
|--SubModuleA
|-BaseModule
|--SubModuleB
|-BaseModule
SubModuleA and SubModuleBare intended to be used seperatly but also in one application like in this example. And both install the same BaseModule.
Guice allows to declare the same bindings several times if they are exactly the same. In another SO-thread this is referred to as "binding de-duplication".
This works fine for simple bindings, but using a FactoryModuleBuilder in the BaseModule results in a CreationException complaining that
"A binding to ... was already configured at [...]FactoryModuleBuilder$1.configure()"
I checked, that the binding really is declared only in one Module. And removing the binding results into an error stating that the binding is missing. So I assume that it is not possible to declare the same binding more than one time using a FactoryModuleBuilder. Is that true? Is there a way around this?
Yes, you can get around this by instead doing
Root
|--BaseModule
|--SubModuleA
|--SubModuleB
All modules together define the registered bindings of the injector. Only in special cases should it be actually necessary to install another module inside of a module, apart from readability.
Related
I am trying out the toothpick DI library and I seem to miss something crucial.
I created the following test project on github where I tried to make a smallest possible use case for my understanding issue.
There you will find the ApplicationModule where I try to inject everything I need in my "root" module. As you can see there, I have twice scope.installModules(module) because my PlainPojo depends on the Application instance. If I do not do the first installModule call, I have no application instance in the scope. I could, as mentioned in the comment, pass the application instance as a parameter but I thought that I can remove them when I use DI?
The second class that causes troubles is the SimpleTest class. If I do not call the inject() method in the constructor, the PlainPojo member will not be injected. I also tried to use a third time the installModules() in the ApplicationModule after binding the PlainPojo but that does not help.
Am I so wrong to assume that an #Inject on a member is enough to automatically inject it when it is available in the scope and that the order of binding is enough to make previous bindings available without installing in between (like done in ApplicationModule)?
If I can provide anything more to make my issue(s) understandable please leave a comment.
Thanks in advance!
Toothpick can only inject dependencies automatically when it creates the instance of the depended object itself (e.g it is annotated with #Singleton or there is a direct binding for the class).
Otherwise you have to manually call Toothpick.inject, just like you do in SimpleTest. There is no way for TP to know when you call the constructor of PlainPojo.
You could just use
module.bind(PlainPojo.class);
module.bind(SimpleTest.class);
and maybe scope them as singletons if needed.
Is it possible to load the value for the #PATH annotation from configuration (web.xml, etc) for a given class?
#Path(<value loaded from config>)
public class myRestService {
...
Independent of JAX-RS: Annotations in Java are compile time constants so they can't be changed at runtime.
I don't know your use case but possible ways to change the values of the annotations are:
Replacing variables before compilation, e.g. through a maven plugin.
Adding the #Path annotations dynamically like described here.
Using one generic ResourceClass mapped to /* which decides which subresource should be returned.
No comment if one of these approaches makes sense as I don't know why you want to change them. As the URI names a resource I don't see any reason to change it. See also: Cool URIs don't change
Update: JAX_RS_SPEC-60 requests "A Dynamic way to register JAX-RS resources (not based on annotations)".
According to JAX-RS specification (here), there is no standard way to do this, I think.
I saw this line in Nexus OSS code ...
#Inject
public ReleaseRemoverTask( final ReleaseRemover releaseRemover )
{
this.releaseRemover = checkNotNull( releaseRemover );
}
the above is found in https://github.com/sonatype/nexus-oss/blob/master/components/nexus-core/src/main/java/org/sonatype/nexus/maven/tasks/ReleaseRemoverTask.java
But ReleaseRemover.java is an interface .
There is no use in interface here , so only the implementation should be passed during runtime ..This only makes sense ..
So I confirmed it by debugging , that the implementation is called .The implementation class was DefaultReleaseRemover.java .
To support my argument I wrote a plugin for nexus and I wrote an implementation for ReleaseRemover .
Even that was picked up ...
How is this done ?
Internally they are using Google Guice ..
Is Guice doing this job of passing the implementations inside this function ?
Is this the property of frameworks like Google Guice ?
If all implementations are passed like this , can I prevent an implementation from being passed ?
you question is not clear for me. What do you want to achieve? What means can I prevent an implementation from being passed ? what you want to pass instead? Null or your implementation?
You are right about that Nexus OSS uses Google Guice as Dependency injection framework. To bind an implementation to some interface you have to create modules where you say something like this:
bind(ReleaseRemover.class).to(DefaultReleaseRemover.class);
As you see in DefaultReleaseRemover there are another injections and they very likely stuck up. So the injected implementation in DefaultReleaseRemover contains another injections and so on.
The DefaultReleaseRemover is annotated as #Singleton which means there is only one instance of DefaultReleaseRemover class for whole injector.
Well, you have your interface and implementation and your module with bindings. Now you need to create Guice Injector and use it to create all objects for you.
For Nexus OSS you can find Guice Injection entry point at https://github.com/sonatype/nexus-oss/blob/de6a606372349283f78aeaa498e9a70d4dd967b1/components/nexus-webapp/src/main/java/org/sonatype/nexus/webapp/WebappBootstrap.java line 118
Guice.createInjector(your modules...);
See, you will provide all modules you want to install to the Guice Injector. Be aware there could be some sub modules installed inside modules. You dont have to explicitly pass it into createInjector function. So, if you want to change some Guice bindings it's good start to dig from there.
UPDATE:
I don't know the mechanics. But you have to bind your implementation in some Module.configuration() as
bind(ReleaseRemover.class).annotathedWith(Names.named("custom")).to(MyCustomReleaseRemover.class);
The module should be not PrivateModule:)
Then you will pass you CustomReleaseRemover as
#Inject
public ReleaseRemoverTask( final #Named("custom") ReleaseRemover releaseRemover )
I would direct you more straight forward, but I have no idea how it works inside Nexus OSS. Maybe somebody could you help with that part.
I have an UI component that will be used in several UI module in an application.
I would like to annotate the UI component that to be injected into several other classes in one UI module to be a singleton, but not a singleton across the whole application. So that for each UI module use the UI component, one and only one of the UI component instance is used.
I couldn't find a straight solution for this from the Guice document. So i think maybe I can use annotation to distinguish those instance?
Say in Module A, I annotate all the injection of the UI component with Named("ModuleA"); and in Module B, with Named("ModulaB"). and in the configuration, i tried to use something like:
this.bind(UIComponentA.class)
.annotatedWith(Names.named("ModulaA"))
.to(UIComponentAImpl.class).in(Singleton.class);
this.bind(UIComponentA.class)
.annotatedWith(Names.named("ModulaB"))
.to(UIComponentAImpl.class).in(Singleton.class);
Because UICompoenetAImpl also need to be injected, so I couldn't simply create the instance there. Totally not sure if this works.
And I'm wondering what's the standard way to accomplish this?
One other option might be to use a child injector for each module.
This would allow you to bind a difference instance of UIComponentA in each module. Bind them in the child injector rather than the parent. You would then need to make sure that all of your module's dependencies are built from the right child injector, probably by making sure the root of each module is loaded from the right place.
Because UICompoenetAImpl also need to be injected, so I couldn't simply create the instance there.
I think you can just create UIComponentAImpl there and bind toInstance. When you do so - other beans will be injected in UIComponentAImpl. Please see my example here.
I would like some suggestions and feedback on the best way to structure dependency injection for a system with the structure described below. I'm using Guice and thus would prefer solutions centered around it's annotation-based declarations, not XML-heavy Spring-style configuration.
Consider a set of similar objects, Ball, Box, and Tube, each dependent on a Logger, supplied via the constructor. (This might not be important, but all four classes happen to be singletons --- of the application, not Gang-of-Four, variety.)
A ToyChest class is responsible for creating and managing the three shape objects. ToyChest itself is not dependent on Logger, aside from creating the shape objects which are.
The ToyChest class is instantiated as an application singleton in a Main class.
I'm confused about the best way to construct the shapes in ToyChest. I either (1) need access to a Guice Injector instance already attached to a Module binding Logger to an implementation or (2) need to create a new Injector attached to the right Module.
(1) is accomplished by adding an #Inject Injector injectorfield to ToyChest, but this feels weird because ToyChest doesn't actually have any direct dependencies --- only those of the children it instantiates.
For (2), I'm not sure how to pass in the appropriate Module.
Am I on the right track? Is there a better way to structure this?
The answers to this question mention passing in a Provider instead of using the Injector directly, but I'm not sure how that is supposed to work.
EDIT:
Perhaps a more simple question is: when using Guice, where is the proper place to construct the shapes objects? ToyChest will do some configuration with them, but I suppose they could be constructed elsewhere. ToyChest (as the container managing them), and not Main, just seems to me like the appropriate place to construct them.
A proper way is to have guice construct your dependencies. That is create and configure.
In your situation you should have an injector constructed in the Main. From the injector you get ToyChest. When you obtain ToyChest through the injector its managed by guice and you can depend on it to supply all dependencies properly configured.
In your case you can inject Provider<Ball>, Provider<Box>, etc. in ToyChest and when needed just retrieve instance from the provider. ToyChest is not responsible for constructing the instance, just to use it. You can also check MapBinder if you have a plugin architecture.
So far everything is managed by guice, so the shapes can have their logger injected without the using class knowing about it.
If you have some runtime parameters that you want to pass to the newly created shape instances, you can use AssistedInject.
Just a hint: you are not required to use constructor injection, you can have injection on field or setter, which simplifies the constructor.