I have a scenario where I will need some objects injecting at the start like logging, but then other objects injected on demand. What I don’t know is if in my console application, do I just call:
Guice.createInjector(....)
in my Main function and then when I need another object, the type that I need on demand, do I use a Provider to inject that same object again? I’m having a hard time figuring out the best way to use Guice’s injector for this scenario.
Advertisement
Answer
In general, yes: Inject a Provider
to get your objects later, and don’t hold on to your Injector directly any longer than necessary.
Ideally, your bootstrap should be just that: It should instantiate your Injector and get some sort of whole-application instance. This is particularly important because Guice is helpful for testing, so maximizing the part of the application subject to Guice is a good idea.
public class YourApplication { public static void main(String[] args) { // Only three lines exist outside the object graph. Injector injector = Guice.createInjector(new YourModule1(), new YourModule2()); YourApplication app = injector.getInstance(YourApplication.class); app.run(); } @Inject Provider<YourDep1> depProvider1; @Inject YourDep2 dep2; public void run() { // Here you have access to every @Inject field. } }
Here, bear in mind that the Injector you created is only kept on the stack. This is because you get everything you need from @Inject
-annotated fields, methods, and constructors, including the Injector itself. As you suggested, you can use a Provider
to get as many instances as you need, including zero instances if the object isn’t necessary in that code path.