Author: limpbizkit
Date: Mon Mar 2 21:11:39 2009
New Revision: 898
Modified:
wiki/BuiltInBindings.wiki
Log:
Edited wiki page through web user interface.
Modified: wiki/BuiltInBindings.wiki
==============================================================================
--- wiki/BuiltInBindings.wiki (original)
+++ wiki/BuiltInBindings.wiki Mon Mar 2 21:11:39 2009
@@ -2,106 +2,6 @@
=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.
{{{
@@ -126,9 +26,9 @@
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=
+=!TypeLiterals=
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=
+=The Stage=
Guice supports a stage enum to differentiate between development and
production runs.
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---