Binder.requestInjection, as implemented by Mike Ward.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@534 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/AbstractModule.java b/src/com/google/inject/AbstractModule.java
index 92cd0ba..62d1fb7 100644
--- a/src/com/google/inject/AbstractModule.java
+++ b/src/com/google/inject/AbstractModule.java
@@ -142,6 +142,13 @@
}
/**
+ * @see Binder#requestInjection(Object[])
+ */
+ protected void requestInjection(Object... objects) {
+ binder.requestInjection(objects);
+ }
+
+ /**
* @see Binder#requestStaticInjection(Class[])
*/
protected void requestStaticInjection(Class<?>... types) {
diff --git a/src/com/google/inject/Binder.java b/src/com/google/inject/Binder.java
index e35a732..dafbb74 100644
--- a/src/com/google/inject/Binder.java
+++ b/src/com/google/inject/Binder.java
@@ -225,6 +225,14 @@
AnnotatedConstantBindingBuilder bindConstant();
/**
+ * Upon successful creation, the {@link Injector} will inject instance fields
+ * and methods of the given objects.
+ *
+ * @param instances for which members will be injected
+ */
+ void requestInjection(Object... instances);
+
+ /**
* Upon successful creation, the {@link Injector} will inject static fields
* and methods in the given classes.
*
diff --git a/src/com/google/inject/CommandProcessor.java b/src/com/google/inject/CommandProcessor.java
index 918cb57..4b806a7 100644
--- a/src/com/google/inject/CommandProcessor.java
+++ b/src/com/google/inject/CommandProcessor.java
@@ -24,6 +24,7 @@
import com.google.inject.commands.Command;
import com.google.inject.commands.ConvertToTypesCommand;
import com.google.inject.commands.GetProviderCommand;
+import com.google.inject.commands.RequestInjectionCommand;
import com.google.inject.commands.RequestStaticInjectionCommand;
import com.google.inject.internal.Errors;
import java.util.Iterator;
@@ -74,6 +75,10 @@
return false;
}
+ public Boolean visitRequestInjection(RequestInjectionCommand command) {
+ return false;
+ }
+
public Boolean visitRequestStaticInjection(RequestStaticInjectionCommand command) {
return false;
}
diff --git a/src/com/google/inject/InjectorBuilder.java b/src/com/google/inject/InjectorBuilder.java
index b026a89..313fb51 100644
--- a/src/com/google/inject/InjectorBuilder.java
+++ b/src/com/google/inject/InjectorBuilder.java
@@ -55,7 +55,7 @@
private final List<Command> commands = Lists.newArrayList();
private BindCommandProcessor bindCommandProcesor;
- private RequestStaticInjectionCommandProcessor requestStaticInjectionCommandProcessor;
+ private RequestInjectionCommandProcessor requestInjectionCommandProcessor;
/**
* @param stage we're running in. If the stage is {@link Stage#PRODUCTION}, we will eagerly load
@@ -147,10 +147,9 @@
injector.index();
stopwatch.resetAndLog("Binding indexing");
- requestStaticInjectionCommandProcessor
- = new RequestStaticInjectionCommandProcessor(errors);
- requestStaticInjectionCommandProcessor
- .processCommands(commands);
+ requestInjectionCommandProcessor
+ = new RequestInjectionCommandProcessor(errors, injector.outstandingInjections);
+ requestInjectionCommandProcessor.processCommands(commands);
stopwatch.resetAndLog("Static injection");
}
@@ -159,7 +158,7 @@
bindCommandProcesor.runCreationListeners(injector);
stopwatch.resetAndLog("Validation");
- requestStaticInjectionCommandProcessor.validate(injector);
+ requestInjectionCommandProcessor.validate(injector);
stopwatch.resetAndLog("Static validation");
injector.validateOustandingInjections(errors);
@@ -175,7 +174,7 @@
private void fulfillInjectionRequests() {
futureInjector.initialize(injector);
- requestStaticInjectionCommandProcessor.injectMembers(injector);
+ requestInjectionCommandProcessor.injectMembers(injector);
stopwatch.resetAndLog("Static member injection");
injector.fulfillOutstandingInjections(errors);
diff --git a/src/com/google/inject/RequestStaticInjectionCommandProcessor.java b/src/com/google/inject/RequestInjectionCommandProcessor.java
similarity index 80%
rename from src/com/google/inject/RequestStaticInjectionCommandProcessor.java
rename to src/com/google/inject/RequestInjectionCommandProcessor.java
index 132ff54..30a1551 100644
--- a/src/com/google/inject/RequestStaticInjectionCommandProcessor.java
+++ b/src/com/google/inject/RequestInjectionCommandProcessor.java
@@ -18,23 +18,29 @@
import com.google.common.collect.Lists;
import com.google.inject.InjectorImpl.SingleMemberInjector;
+import com.google.inject.commands.RequestInjectionCommand;
import com.google.inject.commands.RequestStaticInjectionCommand;
import com.google.inject.internal.Errors;
import com.google.inject.internal.ErrorsException;
import java.util.List;
+import java.util.Set;
/**
- * Handles {@link Binder#requestStaticInjection} commands.
+ * Handles {@link Binder#requestInjection} and {@link Binder#requestStaticInjection} commands.
*
* @author crazybob@google.com (Bob Lee)
* @author jessewilson@google.com (Jesse Wilson)
+ * @author mikeward@google.com (Mike Ward)
*/
-class RequestStaticInjectionCommandProcessor extends CommandProcessor {
+class RequestInjectionCommandProcessor extends CommandProcessor {
private final List<StaticInjection> staticInjections = Lists.newArrayList();
+ private final Set<Object> outstandingInjections;
- RequestStaticInjectionCommandProcessor(Errors errors) {
+ RequestInjectionCommandProcessor(Errors errors,
+ Set<Object> outstandingInjections) {
super(errors);
+ this.outstandingInjections = outstandingInjections;
}
@Override public Boolean visitRequestStaticInjection(RequestStaticInjectionCommand command) {
@@ -44,6 +50,13 @@
return true;
}
+ @Override public Boolean visitRequestInjection(RequestInjectionCommand command) {
+ for (Object instance : command.getInstances()) {
+ outstandingInjections.add(instance);
+ }
+ return true;
+ }
+
public void validate(InjectorImpl injector) {
for (StaticInjection staticInjection : staticInjections) {
staticInjection.validate(injector);
diff --git a/src/com/google/inject/commands/Command.java b/src/com/google/inject/commands/Command.java
index e87f67e..01e06cb 100644
--- a/src/com/google/inject/commands/Command.java
+++ b/src/com/google/inject/commands/Command.java
@@ -32,6 +32,7 @@
V visitAddMessage(AddMessageCommand command);
V visitBindInterceptor(BindInterceptorCommand command);
V visitBindScope(BindScopeCommand command);
+ V visitRequestInjection(RequestInjectionCommand command);
V visitRequestStaticInjection(RequestStaticInjectionCommand command);
V visitBindConstant(BindConstantCommand command);
V visitConvertToTypes(ConvertToTypesCommand command);
diff --git a/src/com/google/inject/commands/CommandRecorder.java b/src/com/google/inject/commands/CommandRecorder.java
index 42bb586..1ae4276 100644
--- a/src/com/google/inject/commands/CommandRecorder.java
+++ b/src/com/google/inject/commands/CommandRecorder.java
@@ -123,6 +123,10 @@
commands.add(new BindScopeCommand(getSource(), annotationType, scope));
}
+ public void requestInjection(Object... instances) {
+ commands.add(new RequestInjectionCommand(getSource(), instances));
+ }
+
public void requestStaticInjection(Class<?>... types) {
commands.add(new RequestStaticInjectionCommand(getSource(), types));
}
diff --git a/src/com/google/inject/commands/CommandReplayer.java b/src/com/google/inject/commands/CommandReplayer.java
index a666737..05c668b 100644
--- a/src/com/google/inject/commands/CommandReplayer.java
+++ b/src/com/google/inject/commands/CommandReplayer.java
@@ -69,6 +69,11 @@
return null;
}
+ public Void visitRequestInjection(RequestInjectionCommand command) {
+ replayRequestInjection(binder, command);
+ return null;
+ }
+
public Void visitRequestStaticInjection(RequestStaticInjectionCommand command) {
replayRequestStaticInjection(binder, command);
return null;
@@ -116,6 +121,13 @@
command.getAnnotationType(), command.getScope());
}
+ public void replayRequestInjection(final Binder binder,
+ final RequestInjectionCommand command) {
+ List<Object> objects = command.getInstances();
+ binder.withSource(command.getSource())
+ .requestInjection(objects.toArray());
+ }
+
public void replayRequestStaticInjection(final Binder binder,
final RequestStaticInjectionCommand command) {
List<Class> types = command.getTypes();
diff --git a/src/com/google/inject/commands/DefaultCommandVisitor.java b/src/com/google/inject/commands/DefaultCommandVisitor.java
index cf98592..91139dd 100644
--- a/src/com/google/inject/commands/DefaultCommandVisitor.java
+++ b/src/com/google/inject/commands/DefaultCommandVisitor.java
@@ -62,6 +62,10 @@
return visitCommand(command);
}
+ public V visitRequestInjection(RequestInjectionCommand command) {
+ return visitCommand(command);
+ }
+
public V visitRequestStaticInjection(
RequestStaticInjectionCommand command) {
return visitCommand(command);
diff --git a/src/com/google/inject/commands/RequestInjectionCommand.java b/src/com/google/inject/commands/RequestInjectionCommand.java
new file mode 100644
index 0000000..f47c799
--- /dev/null
+++ b/src/com/google/inject/commands/RequestInjectionCommand.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.commands;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+
+/**
+ * Immutable snapshot of a request for injection.
+ *
+ * @author mikeward@google.com (Mike Ward)
+ */
+public final class RequestInjectionCommand implements Command {
+ private Object source;
+ private List<Object> instances;
+
+ public RequestInjectionCommand(Object source, Object[] instances) {
+ this.source = checkNotNull(source, "source");
+ this.instances = ImmutableList.of(instances);
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+ public List<Object> getInstances() {
+ return instances;
+ }
+
+ public <T> T acceptVisitor(Visitor<T> visitor) {
+ return visitor.visitRequestInjection(this);
+ }
+}
diff --git a/src/com/google/inject/commands/RequestStaticInjectionCommand.java b/src/com/google/inject/commands/RequestStaticInjectionCommand.java
index 564eead..b1ce316 100644
--- a/src/com/google/inject/commands/RequestStaticInjectionCommand.java
+++ b/src/com/google/inject/commands/RequestStaticInjectionCommand.java
@@ -17,10 +17,9 @@
package com.google.inject.commands;
-import java.util.Arrays;
-import static java.util.Collections.unmodifiableList;
-import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
/**
* Immutable snapshot of a request for static injection.
@@ -33,7 +32,7 @@
RequestStaticInjectionCommand(Object source, Class[] types) {
this.source = checkNotNull(source, "source");
- this.types = unmodifiableList(Arrays.asList(types.clone()));
+ this.types = ImmutableList.of(types);
}
public Object getSource() {
diff --git a/test/com/google/inject/AllTests.java b/test/com/google/inject/AllTests.java
index dfc78e8..2c447d4 100644
--- a/test/com/google/inject/AllTests.java
+++ b/test/com/google/inject/AllTests.java
@@ -68,7 +68,7 @@
suite.addTestSuite(ReflectionTest.class);
suite.addTestSuite(ScopesTest.class);
suite.addTestSuite(SerializationTest.class);
- suite.addTestSuite(StaticInjectionTest.class);
+ suite.addTestSuite(RequestInjectionTest.class);
suite.addTestSuite(SuperclassTest.class);
suite.addTestSuite(TypeLiteralTest.class);
diff --git a/test/com/google/inject/RequestInjectionTest.java b/test/com/google/inject/RequestInjectionTest.java
new file mode 100644
index 0000000..18f6994
--- /dev/null
+++ b/test/com/google/inject/RequestInjectionTest.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2006 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject;
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import junit.framework.TestCase;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class RequestInjectionTest extends TestCase {
+
+ @Retention(RUNTIME)
+ @BindingAnnotation @interface ForField {}
+
+ @Retention(RUNTIME)
+ @BindingAnnotation @interface ForMethod {}
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ HasInjections.staticField = 0;
+ HasInjections.staticMethod = null;
+ }
+
+ public void testInjectMembers() {
+ final HasInjections hi = new HasInjections();
+
+ Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bindConstant().annotatedWith(ForMethod.class).to("test");
+ bindConstant().annotatedWith(ForField.class).to(5);
+ requestInjection(hi);
+ }
+ });
+
+ assertEquals("test", hi.instanceMethod);
+ assertEquals(5, hi.instanceField);
+ assertNull(HasInjections.staticMethod);
+ assertEquals(0, HasInjections.staticField);
+ }
+
+ public void testInjectStatics() throws CreationException {
+ Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bindConstant().annotatedWith(ForMethod.class).to("test");
+ bindConstant().annotatedWith(ForField.class).to(5);
+ requestStaticInjection(HasInjections.class);
+ }
+ });
+
+ assertEquals("test", HasInjections.staticMethod);
+ assertEquals(5, HasInjections.staticField);
+ }
+
+ public void testInjectMembersAndStatics() {
+ final HasInjections hi = new HasInjections();
+
+ Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bindConstant().annotatedWith(ForMethod.class).to("test");
+ bindConstant().annotatedWith(ForField.class).to(5);
+ requestStaticInjection(HasInjections.class);
+ requestInjection(hi);
+ }
+ });
+
+ assertEquals("test", hi.instanceMethod);
+ assertEquals(5, hi.instanceField);
+ assertEquals("test", HasInjections.staticMethod);
+ assertEquals(5, HasInjections.staticField);
+ }
+
+ static class HasInjections {
+
+ @Inject @ForField static int staticField;
+ @Inject @ForField int instanceField;
+
+ static String staticMethod;
+ String instanceMethod;
+
+ @Inject static void setStaticMethod(@ForMethod String staticMethod) {
+ HasInjections.staticMethod = staticMethod;
+ }
+
+ @Inject void setInstanceS(@ForMethod String instanceS) {
+ this.instanceMethod = instanceS;
+ }
+ }
+}
diff --git a/test/com/google/inject/StaticInjectionTest.java b/test/com/google/inject/StaticInjectionTest.java
deleted file mode 100644
index 6f1ac5f..0000000
--- a/test/com/google/inject/StaticInjectionTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Copyright (C) 2006 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.inject;
-
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import junit.framework.TestCase;
-
-/**
- * @author crazybob@google.com (Bob Lee)
- */
-public class StaticInjectionTest extends TestCase {
-
- @Retention(RUNTIME)
- @BindingAnnotation @interface I {}
-
- @Retention(RUNTIME)
- @BindingAnnotation @interface S {}
-
- public void testInjectStatics() throws CreationException {
- Guice.createInjector(new AbstractModule() {
- protected void configure() {
- bindConstant().annotatedWith(S.class).to("test");
- bindConstant().annotatedWith(I.class).to(5);
- requestStaticInjection(StaticInjectionTest.Static.class);
- }
- });
-
- assertEquals("test", StaticInjectionTest.Static.s);
- assertEquals(5, StaticInjectionTest.Static.i);
- }
-
- static class Static {
-
- @Inject @I static int i;
-
- static String s;
-
- @Inject static void setS(@S String s) {
- StaticInjectionTest.Static.s = s;
- }
- }
-}
diff --git a/test/com/google/inject/commands/CommandRecorderTest.java b/test/com/google/inject/commands/CommandRecorderTest.java
index d3136c9..47e69f2 100644
--- a/test/com/google/inject/commands/CommandRecorderTest.java
+++ b/test/com/google/inject/commands/CommandRecorderTest.java
@@ -552,6 +552,26 @@
);
}
+ public void testRequestInjection() {
+ final Object firstObject = new Object();
+ final Object secondObject = new Object();
+
+ checkModule(
+ new AbstractModule() {
+ protected void configure() {
+ requestInjection(firstObject, secondObject);
+ }
+ },
+
+ new FailingVisitor() {
+ @Override public Void visitRequestInjection(RequestInjectionCommand command) {
+ assertEquals(Arrays.asList(firstObject, secondObject), command.getInstances());
+ return null;
+ }
+ }
+ );
+ }
+
public void testRequestStaticInjection() {
checkModule(
new AbstractModule() {
@@ -774,6 +794,10 @@
throw new AssertionFailedError();
}
+ public Void visitRequestInjection(RequestInjectionCommand command) {
+ throw new AssertionFailedError();
+ }
+
public Void visitRequestStaticInjection(RequestStaticInjectionCommand command) {
throw new AssertionFailedError();
}