Author: limpbizkit
Date: Mon Mar 2 16:07:11 2009
New Revision: 884
Added:
wiki/BuiltInBindings.wiki
Log:
Created wiki page through web user interface.
Added: wiki/BuiltInBindings.wiki
==============================================================================
--- (empty file)
+++ wiki/BuiltInBindings.wiki Mon Mar 2 16:07:11 2009
@@ -0,0 +1,134 @@
+#summary More bindings that you can use
+=Built-in Bindings=
+Alongside [CreatingBindings explicit], and [JustInTimeBindings
just-in-time bindings], additional bindings are built into the injector.
Only the injector can create these bindings and attempting to bind them by
hand is an error.
+
+==Providers==
+With normal dependency injection, each type gets exactly *one instance* of
each of its dependent types. The `RealBillingService` gets one
`CreditCardProcessor` and one `TransactionLog`. When this flexibility is
necessary, Guice binds a provider. Providers produce a value when the
`get()` method is invoked:
+{{{
+public interface Provider<T> {
+ T get();
+}
+}}}
+The provider's type is _parameterized_ to differentiate a
`Provider<TransactionLog>` from a `Provider<CreditCardProcessor>`. Wherever
you inject a value you can inject a provider for that value.
+{{{
+public class RealBillingService implements BillingService {
+ private final Provider<CreditCardProcessor> processorProvider;
+ private final Provider<TransactionLog> transactionLogProvider;
+
+ @Inject
+ public RealBillingService(Provider<CreditCardProcessor>
processorProvider,
+ Provider<TransactionLog> transactionLogProvider) {
+ this.processorProvider = processorProvider;
+ this.transactionLogProvider = transactionLogProvider;
+ }
+
+ public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
+ CreditCardProcessor processor = processorProvider.get();
+ TransactionLog transactionLog = transactionLogProvider.get();
+
+ /* use the processor and transaction log here */
+ }
+}
+}}}
+For every binding, annotated or not, the injector has a built-in binding
for its provider.
+
+
+==Providers for multiple instances==
+Use providers when you need multiple instances of the same type. Suppose
your application saves a summary entry and a details when a pizza charge
fails. With providers, you can get a new entry whenever you need one:
+{{{
+public class LogFileTransactionLog implements TransactionLog {
+
+ private final Provider<LogFileEntry> logFileProvider;
+
+ @Inject
+ public LogFileTransactionLog(Provider<LogFileEntry> logFileProvider) {
+ this.logFileProvider = logFileProvider;
+ }
+
+ public void logChargeResult(ChargeResult result) {
+ LogFileEntry summaryEntry = logFileProvider.get();
+ summaryEntry.setText("Charge " +
(result.wasSuccessful() ? "success" : "failure"));
+ summaryEntry.save();
+
+ if (!result.wasSuccessful()) {
+ LogFileEntry detailEntry = logFileProvider.get();
+ detailEntry.setText("Failure result: " + result);
+ detailEntry.save();
+ }
+ }
+}}}
+
+
+==Providers for lazy loading==
+If you've got a dependency on a type that is particularly *expensive to
produce*, you can use providers to defer that work. This is especially
useful when you don't always need the dependency:
+{{{
+public class DatabaseTransactionLog implements TransactionLog {
+
+ private final Provider<Connection> connectionProvider;
+
+ @Inject
+ public DatabaseTransactionLog(Provider<Connection> connectionProvider) {
+ this.connectionProvider = connectionProvider;
+ }
+
+ public void logChargeResult(ChargeResult result) {
+ /* only write failed charges to the database */
+ if (!result.wasSuccessful()) {
+ Connection connection = connectionProvider.get();
+ }
+ }
+}}}
+
+==Providers for Mixing Scopes==
+It is an error to depend on an object in a _narrower_ scope. Suppose you
have a singleton transaction log that needs on the request-scoped current
user. Should you inject the user directly, things break because the user
changes from request to request. Since providers can produce values
on-demand, they enable you to mix scopes safely:
+{{{
+...@singleton
+public class ConsoleTransactionLog implements TransactionLog {
+
+ private final AtomicInteger failureCount = new AtomicInteger();
+ private final Provider<User> userProvider;
+
+ @Inject
+ public ConsoleTransactionLog(Provider<User> userProvider) {
+ this.userProvider = userProvider;
+ }
+
+ public void logConnectException(UnreachableException e) {
+ failureCount.incrementAndGet();
+ User user = userProvider.get();
+ System.out.println("Connection failed for " + user + ": " +
e.getMessage());
+ System.out.println("Failure count: " + failureCount.incrementAndGet());
+ }
+}}}
+
+
+=Loggers=
+Guice has a built-in binding for `java.util.logging.Logger`, intended to
save some boilerplate. The binding automatically sets the logger's name to
the name of the injected class.
+{{{
+...@singleton
+public class ConsoleTransactionLog implements TransactionLog {
+
+ private final Logger logger;
+
+ @Inject
+ public ConsoleTransactionLog(Logger logger) {
+ this.logger = logger;
+ }
+
+ public void logConnectException(UnreachableException e) {
+ /* the message is logged to the "ConsoleTransacitonLog" logger */
+ logger.warning("Connect exception failed, " + e.getMessage());
+ }
+}}}
+
+
+=The Injector=
+In framework code, sometimes you don't know the type you need until
runtime. In this rare case you should inject the injector. Code that
injects the injector does not self-document its dependencies, so this
approach should be done sparingly.
+
+
+=TypeLiteral=
+Guice has complete type information for everything it injects. If you're
injecting parameterized types, you can inject a `TypeLiteral<T>` to
reflectively tell you the element type.
+
+
+=Stage=
+Guice supports a stage enum to differentiate between development and
production runs.
\ No newline at end of file
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---