18

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?

Ben Glasser
  • 3,216
  • 3
  • 24
  • 41

1 Answers1

20

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.

Tavian Barnes
  • 12,477
  • 4
  • 45
  • 118
  • How about the relationship of all this with javax.inject? Neither in your code nor the OP's we see what annotations are imported; this may have an impact if I'm not mistaken? – fge Dec 15 '14 at 21:27
  • There should be no difference. The only difference I'm aware of is Guice will refuse to inject into `final` fields with `@javax.inject.Inject`, but it will try with `@com.google.inject.Inject`. – Tavian Barnes Dec 15 '14 at 22:22
  • @fge Also there is no `javax.inject.Provides` – Tavian Barnes Dec 16 '14 at 01:05