My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
ProviderBindings  
Updated Oct 16, 2011 by sberlin

Provider Bindings

When your @Provides methods start to grow complex, you may consider moving them to a class of their own. The provider class implements Guice's Provider interface, which is a simple, general interface for supplying values:

public interface Provider<T> {
  T get();
}

Our provider implementation class has dependencies of its own, which it receives via its @Inject-annotated constructor. It implements the Provider interface to define what's returned with complete type safety:

public class DatabaseTransactionLogProvider implements Provider<TransactionLog> {
  private final Connection connection;

  @Inject
  public DatabaseTransactionLogProvider(Connection connection) {
    this.connection = connection;
  }

  public TransactionLog get() {
    DatabaseTransactionLog transactionLog = new DatabaseTransactionLog();
    transactionLog.setConnection(connection);
    return transactionLog;
  }
}

Finally we bind to the provider using the .toProvider clause:

public class BillingModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(TransactionLog.class)
        .toProvider(DatabaseTransactionLogProvider.class);
  }

If your providers are complex, be sure to test them!

Throwing Exceptions

Guice does not allow exceptions to be thrown from Providers. The Provider interface does not allow for checked exception to be thrown. RuntimeExceptions may be wrapped in a ProvisionException or CreationException and may prevent your Injector from being created. If you need to throw an exception for some reason, you may want to use the ThrowingProviders extension.

Comment by thang...@gmail.com, Apr 22, 2010

This case is interesting. Does it really work? I am guessing that when asking Guice for BillingService? instance, it either throws runtime exception due to there is no default constructor or TransactionLog? with 'connection' attribute is null.

Comment by jerzy.cz...@gmail.com, Apr 27, 2010

Can providers provide us with a singleton?

Comment by khan.sha...@gmail.com, Aug 4, 2010

Must always test them !!!! not just when they are complex :)

I suppose you would need connection configured in module as well . If this is the module being used for Injector.

Comment by mcsekhar...@gmail.com, Aug 9, 2010

I think providers would be able to give singletons with @Singleton defined.

Comment by pljosh.m...@gmail.com, Sep 27, 2010

If you want your provider to produce instance per whatever scope, like e.g. @Singleton, just define scope when binding:

bind(TransactionLog?.class).toProvider(DatabaseTransactionLogProvider?.class).in(Singleton.class); (or any other available scope).

Comment by dean.hil...@broadridge.com, Feb 17, 2011

how about creating a Provider dynamically? I have a Class var = annotation.getValue(); and I want to create a Provider of Provider<var> but I don't know what var is until runtime. Is there a way to do that? I was looking at http://eng.wealthfront.com/2010/05/just-in-time-providers-for-guice.html which is pretty cool stuff and would work(as a different paradigm of course) but was hoping I could use straight guice with no changes to create a list of Providers instead that could provide the stuff(this is all from annotation scanning to hook up some @TriggerImpl?(xxxxx.class) on some bean.


Sign in to add a comment
Powered by Google Project Hosting