Author: limpbizkit
Date: Wed Oct 15 16:49:00 2008
New Revision: 635
Modified:
trunk/extensions/privatemodules/src/com/google/inject/privatemodules/PrivateModule.java
trunk/extensions/privatemodules/test/com/google/inject/privatemodules/PrivateModuleTest.java
Log:
Crazy circular-dependency tests for private modules, plus a fix to make
them work.
The most interesting works around a problem where the providers for
singletons can be called multiple times. This happens when the provider
uses its own singleton in processing.
Modified:
trunk/extensions/privatemodules/src/com/google/inject/privatemodules/PrivateModule.java
==============================================================================
---
trunk/extensions/privatemodules/src/com/google/inject/privatemodules/PrivateModule.java
(original)
+++
trunk/extensions/privatemodules/src/com/google/inject/privatemodules/PrivateModule.java
Wed Oct 15 16:49:00 2008
@@ -92,7 +92,7 @@
private final SourceProvider sourceProvider
= new SourceProvider().plusSkippedClasses(PrivateModule.class);
- /** When this provider returns, the private injector is ready. */
+ /** When this provider returns, the private injector creation has
started. */
private Provider<Ready> readyProvider;
/** Keys exposed to the public injector */
@@ -148,13 +148,20 @@
}
}
- // create the private injector while the public injector is
injecting its members
+ // create the private injector while the public injector is
injecting its members. This is
+ // necessary so the providers from getProvider() will work.
publicBinder.bind(readyKey).toProvider(new Provider<Ready>() {
@Inject Injector publicInjector;
+ private Ready result;
public Ready get() {
- // this is necessary so the providers from getProvider() will
work
- publicInjector.createChildInjector(privateModule);
- return new Ready();
+ // Build the child injector once. This method is called multiple
times when we have
+ // creation-time dependencies from private on public and from
public to private.
+ if (result == null) {
+ result = new Ready();
+ publicInjector.createChildInjector(privateModule);
+ }
+
+ return result;
}
}).asEagerSingleton();
@@ -209,7 +216,7 @@
void annotatedWith(Annotation annotation);
}
- /** A binding from the private injector exposed to the public injector.
*/
+ /** A binding from the private injector make visible to the public
injector. */
private static class Expose<T> implements ExposedKeyBuilder, Provider<T>
{
private final Object source;
private final Provider<Ready> readyProvider;
@@ -264,6 +271,9 @@
return privatelyBoundKeys;
}
+
+ // prevent classes migrated from AbstractModule from implementing the
wrong method.
+ protected final void configure() {}
// everything below is copied from AbstractModule
Modified:
trunk/extensions/privatemodules/test/com/google/inject/privatemodules/PrivateModuleTest.java
==============================================================================
---
trunk/extensions/privatemodules/test/com/google/inject/privatemodules/PrivateModuleTest.java
(original)
+++
trunk/extensions/privatemodules/test/com/google/inject/privatemodules/PrivateModuleTest.java
Wed Oct 15 16:49:00 2008
@@ -23,6 +23,7 @@
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
+import com.google.inject.Provider;
import com.google.inject.Provides;
import com.google.inject.name.Named;
import static com.google.inject.name.Names.named;
@@ -181,8 +182,114 @@
assertEquals("nested", injector.getInstance(String.class));
}
+ public void testDependenciesBetweenPrivateAndPublic() {
+ Injector injector = Guice.createInjector(
+ new PrivateModule() {
+ protected void configurePrivateBindings() {}
+
+ @Provides @Exposed @Named("a") String provideA() {
+ return "A";
+ }
+
+ @Provides @Exposed @Named("abc") String provideC(@Named("ab")
String ab) {
+ return ab + "C";
+ }
+ },
+ new AbstractModule() {
+ protected void configure() {}
+
+ @Provides @Named("ab") String provideB(@Named("a") String a) {
+ return a + "B";
+ }
+
+ @Provides @Named("abcd") String provideD(@Named("abc") String
abc) {
+ return abc + "D";
+ }
+ }
+ );
+
+ assertEquals("ABCD", injector.getInstance(Key.get(String.class,
named("abcd"))));
+ }
+
+ public void
testDependenciesBetweenPrivateAndPublicWithPublicEagerSingleton() {
+ Injector injector = Guice.createInjector(
+ new PrivateModule() {
+ protected void configurePrivateBindings() {}
+
+ @Provides @Exposed @Named("a") String provideA() {
+ return "A";
+ }
+
+ @Provides @Exposed @Named("abc") String provideC(@Named("ab")
String ab) {
+ return ab + "C";
+ }
+ },
+ new AbstractModule() {
+ protected void configure() {
+
bind(String.class).annotatedWith(named("abcde")).toProvider(new
Provider<String>() {
+ @Inject @Named("abcd") String abcd;
+
+ public String get() {
+ return abcd + "E";
+ }
+ }).asEagerSingleton();
+ }
+
+ @Provides @Named("ab") String provideB(@Named("a") String a) {
+ return a + "B";
+ }
+
+ @Provides @Named("abcd") String provideD(@Named("abc") String
abc) {
+ return abc + "D";
+ }
+ }
+ );
+
+ assertEquals("ABCDE", injector.getInstance(Key.get(String.class,
named("abcde"))));
+ }
+
+ public void
testDependenciesBetweenPrivateAndPublicWithPrivateEagerSingleton() {
+ Injector injector = Guice.createInjector(
+ new AbstractModule() {
+ protected void configure() {}
+
+ @Provides @Named("ab") String provideB(@Named("a") String a) {
+ return a + "B";
+ }
+
+ @Provides @Named("abcd") String provideD(@Named("abc") String
abc) {
+ return abc + "D";
+ }
+ },
+ new PrivateModule() {
+ protected void configurePrivateBindings() {
+
bind(String.class).annotatedWith(named("abcde")).toProvider(new
Provider<String>() {
+ @Inject @Named("abcd") String abcd;
+
+ public String get() {
+ return abcd + "E";
+ }
+ }).asEagerSingleton();
+ expose(String.class).annotatedWith(named("abcde"));
+ }
+
+ @Provides @Exposed @Named("a") String provideA() {
+ return "A";
+ }
+
+ @Provides @Exposed @Named("abc") String provideC(@Named("ab")
String ab) {
+ return ab + "C";
+ }
+ }
+ );
+
+ assertEquals("ABCDE", injector.getInstance(Key.get(String.class,
named("abcde"))));
+ }
+
static class AB {
@Inject @Named("a") String a;
@Inject @Named("b") String b;
}
+
+ interface C {}
}
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---