I am hoping to redefine or update some bindings within a Module which is in turn used by an Injector. I realise that Modules are immutable and once a binding is sucked and injected its definition cannot change for all practical purposes.
I would like to add/change/remove bindings while keeping singletons already living in an Injector. Changing is a simple case as one can achieve this effecct by using a Provider. However dynamically adding or removing a Key (binding definition) is a bit more tricky.
Any thoughts if this should or can be practically done.
I am thinking the best way is to recreate an injector each time an add/remove binding occurs copying definitions from the original to the new one, Any existing singletons would be redefined by toInstance rather than to implementation type etc.
Binding is to Guice as wiring is to Spring. With bindings, we define how Guice is going to inject dependencies into a class. This module implementation specifies that an instance of DefaultCommunicatorImpl is to be injected wherever a Communicator variable is found.
public interface Injector. Builds the graphs of objects that make up your application. The injector tracks the dependencies for each type and uses bindings to inject them. This is the core of Guice, although you rarely interact with it directly.
A module contributes configuration information, typically interface bindings, which will be used to create an Injector . A Guice-based application is ultimately composed of little more than a set of Module s and some bootstrapping code.
Child injectors can be used to accomplish this, but it requires some setup. Child injectors will prevent long-lived bindings from depending on short-lived ones. Here's an example:
class ForeverModule extends AbstractModule {
...
}
class TemporaryModule extends AbstractModule {
...
}
class Main {
public static void main(String... args) {
Injector foreverInjector = Guice.createInjector(new ForeverModule());
Injector injector = foreverInjector.createChildInjector(
new TemporaryModule());
/*
* Do stuff with the injector as you would normally. When you
* get bored of that injector, create a replacement injector
* as a child of the long-lived injector.
*/
}
}
Singleton bindings in the forever module will last as long as that module exists. Singleton bindings in the temporary module will last as long as you're using the corresponding injector.
Warning: By default, just-in-time bindings will be created in the top-level injector. If you need a binding to be short-lived, you need to bind both the interface and the implementation in your child injector's module. That looks like this:
public void configure() {
bind(Foo.class).to(RealFoo.class);
bind(RealFoo.class);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With