Ben Glasser
Ben Glasser

Reputation: 3355

In guice is there a difference between @provides and bind()?

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?

Upvotes: 19

Views: 13250

Answers (1)

Tavian Barnes
Tavian Barnes

Reputation: 12922

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.

Upvotes: 20

Related Questions