I have a class like so, that I create myself somewhere in my code:
class StarryEyes {
@Inject MyValidator validator;
public StarryEyes(String name) {
//..
}
public doSomething() {
// validator is NULL
}
}
I want Guice to inject an instance of validator, which has a @Singleton annotation.
I have a module that’s loaded at startup and it contains the line:
bind(MyValidator.class);
However, it doesn’t seem to work as “validator” is always null. I’ve tried a number of variations like:
bind(MyValidator.class)toInstance(new MyValidator());
or other things like that. Is this not how Guice is supposed to work?
Typically Guice needs to create objects to inject them. If you just call
new StarryEyes(name), Guice isn’t ever going to see that object so it won’t be able to inject it. One thing you can do is to callinjector.injectMembers(obj)on the object after you’ve created it. I wouldn’t recommend that, though, as you should avoid referencing the injector in your code.What you really probably want here is Assisted Inject. With Assisted Inject, you’d declare the constructor for your class something like this:
What that means is that
validatoris a parameter that Guice should inject, whilenamemust be “assisted” (that is, provided at the time the instance is created).You then create an interface like this:
With Assisted Inject, Guice can then implement that factory for you. You bind it like this:
You then inject a
StarryEyesFactoryanywhere you want to create an instance of it. Where you would have callednew StarryEyes(name)previously, you now callstarryEyesFactory.create(name)instead. When you callcreate(name)on the factory, it will take the name and pass it to the constructor and provide the bound validator itself.Starting in Guice 3, you do this using a FactoryModuleBuilder: