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
-~----------~----~----~----~------~----~------~--~---

Reply via email to