I am wondering what the difference is between using @provides
on a method and using bind()
in my guice modules.
I usually override AbstractModule.configure() and bind all my implementations to my interfaces like this:
public class MyModule extends AbstractModule
{
@Override
protected void configure()
{
this.bind(myIface.class).to(myIfaceImpl.class);
this.bind(myOtherIface.class).to(myOtherIfaceImpl.class).asEagerSingleton();
}
...
}
However, I have noticed a pattern in the codebase I'm currently working with where implementations aren't bound explicitly they are being returned from providers like this:
public class MyModule extends AbstractModule
{
@Provides
@Singleton
myIface iFaceProvider()
{
return new myIfaceImpl();
}
...
}
Is there a reason to prefer one over the other? Are there cases that force a particular method?
A binding is an object that corresponds to an entry in the Guice map. You add new entries into the Guice map by creating bindings.
Guice provides a way to create bindings with complex objects using @provides method. This methods is being part of Binding Module and provides the complex object to be mapped.
Guice provides another way also to map bindings without creating a custom annoation. It allows so using @Named annotation.
Note that the only Guice-specific code in the above is the @Inject annotation. This annotation marks an injection point. Guice will attempt to reconcile the dependencies implied by the annotated constructor, method, or field.
If you do
bind(MyInterface.class).to(MyImplementation.class)
Guice creates the instance for you. This enables certiain things like AOP. If you do
@Provides
MyInterface provideMyInterface() {
return new MyImplementation();
}
then Guice didn't create the instance so AOP won't work. Also, it requires an accessible constructor for MyImplementation
. Generally, this form is only used when you can't edit MyImplementation
to make it Guice-compatible.
There's a third form:
@Provides
MyInterface provideMyInterface(MyImplementation impl) {
return impl;
}
which is almost totally equivalent to the bind(...).to(...)
form. It is commonly used in frameworks like Dagger that do not have the bind
syntax.
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