Revision: 1195
Author: sberlin
Date: Sun Aug 1 09:01:16 2010
Log: issue 528 - if a single PrivateModule is supplied to Modules.override,
allow the private elements within the module to be overridden.
http://code.google.com/p/google-guice/source/detail?r=1195
Modified:
/trunk/src/com/google/inject/util/Modules.java
/trunk/test/com/google/inject/ModulesTest.java
=======================================
--- /trunk/src/com/google/inject/util/Modules.java Sat Jul 3 08:51:31 2010
+++ /trunk/src/com/google/inject/util/Modules.java Sun Aug 1 09:01:16 2010
@@ -22,8 +22,10 @@
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.PrivateBinder;
+import com.google.inject.PrivateModule;
import com.google.inject.Scope;
import com.google.inject.internal.util.ImmutableSet;
+import com.google.inject.internal.util.Iterables;
import com.google.inject.internal.util.Lists;
import com.google.inject.internal.util.Maps;
import com.google.inject.internal.util.Sets;
@@ -52,6 +54,25 @@
public static final Module EMPTY_MODULE = new Module() {
public void configure(Binder binder) {}
};
+
+ /**
+ * Returns a builder that creates a module that overlays override
modules over the given
+ * PrivateModule. This allows private elements in the module to be
overridden. No new keys
+ * may be exposed. If a key is bound in both sets of modules, only the
binding from the override modules
+ * is kept. This can be used to replace the bindings of a production
module with test bindings:
+ * <pre>
+ * Module functionalTestModule
+ * = Modules.override(new
PrivateProductionModule()).with(getTestModules());
+ * </pre>
+ *
+ * <p>Prefer to write smaller modules that can be reused and tested
without overrides.
+ *
+ * @param modules the modules whose bindings are open to be overridden
+ * @since 3.0
+ */
+ public static PrivateOverriddenModuleBuilder override(PrivateModule
privateModule) {
+ return new RealPrivateOverriddenModuleBuilder(privateModule);
+ }
/**
* Returns a builder that creates a module that overlays override
modules over the given
@@ -124,7 +145,53 @@
*/
Module with(Iterable<? extends Module> overrides);
}
-
+
+ /**
+ * See the EDSL example at {...@link Modules#override(PrivateModule)
override()}.
+ * @since 3.0
+ */
+ public interface PrivateOverriddenModuleBuilder {
+
+ /**
+ * See the EDSL example at {...@link Modules#override(PrivateModule)
override()}.
+ */
+ PrivateModule with(Module... overrides);
+
+ /**
+ * See the EDSL example at {...@link Modules#override(PrivateModule)
override()}.
+ */
+ PrivateModule with(Iterable<? extends Module> overrides);
+ }
+
+ /**
+ * An override builder specifically for private modules.
+ * This allows elements within a PrivateModule to be overridden.
+ */
+ private static final class RealPrivateOverriddenModuleBuilder implements
PrivateOverriddenModuleBuilder {
+ private final PrivateModule baseModule;
+
+ private RealPrivateOverriddenModuleBuilder(PrivateModule
privateModule) {
+ this.baseModule = privateModule;
+ }
+
+ public PrivateModule with(Module... overrides) {
+ return with(Arrays.asList(overrides));
+ }
+
+ public PrivateModule with(final Iterable<? extends Module> overrides) {
+ return new PrivateModule() {
+ @Override
+ public void configure() {
+ PrivateElements privateElements =
(PrivateElements)Iterables.getOnlyElement(Elements.getElements(baseModule));
+
override(Elements.getModule(privateElements.getElements())).with(overrides).configure(binder());
+ for(Key exposed : privateElements.getExposedKeys()) {
+
binder().withSource(privateElements.getExposedSource(exposed)).expose(exposed);
+ }
+ }
+ };
+ }
+ }
+
private static final class RealOverriddenModuleBuilder implements
OverriddenModuleBuilder {
private final ImmutableSet<Module> baseModules;
=======================================
--- /trunk/test/com/google/inject/ModulesTest.java Sat Feb 7 11:26:08 2009
+++ /trunk/test/com/google/inject/ModulesTest.java Sun Aug 1 09:01:16 2010
@@ -16,6 +16,9 @@
package com.google.inject;
+import static com.google.inject.name.Names.named;
+
+import com.google.inject.name.Named;
import com.google.inject.util.Modules;
import java.util.Arrays;
import junit.framework.TestCase;
@@ -64,4 +67,49 @@
}
};
}
-}
+
+ private static final String RESULT = "RESULT";
+ private static final String PRIVATE_INPUT = "PRIVATE_INPUT";
+ private static final String OVERRIDDEN_INPUT = "FOO";
+ private static final String OVERRIDDEN_RESULT = "Size: 3";
+ private static final Key<String> RESULT_KEY = Key.get(String.class,
named(RESULT));
+ private static final Key<String> INPUT_KEY = Key.get(String.class,
named(PRIVATE_INPUT));
+
+
+ public void testExposedBindingOverride() throws Exception {
+ Injector inj = Guice.createInjector(
+ Modules.override(new ExampleModule()).with(
+ new AbstractModule() {
+ @Override protected void configure() {
+ bind(RESULT_KEY).toInstance(OVERRIDDEN_RESULT);
+ }
+ }));
+ assertEquals(inj.getInstance(RESULT_KEY), OVERRIDDEN_RESULT);
+ }
+
+ public void testPrivateBindingOverride() throws Exception {
+ Injector inj = Guice.createInjector(
+ Modules.override(new ExampleModule()).with(
+ new AbstractModule() {
+ @Override protected void configure() {
+ bind(INPUT_KEY).toInstance(OVERRIDDEN_INPUT);
+ }
+ }));
+ assertEquals(inj.getInstance(RESULT_KEY), OVERRIDDEN_RESULT);
+ }
+
+ public static class ExampleModule extends PrivateModule {
+ @Provides @Exposed @Named(RESULT)
+ public String provideResult(@Named(PRIVATE_INPUT) String input) {
+ return "Size: " + input.length();
+ }
+
+ @Provides @Named(PRIVATE_INPUT)
+ public String provideInput() {
+ return "Hello World";
+ }
+
+ @Override protected void configure() {
+ }
+ }
+}
--
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.