Author: limpbizkit
Date: Sun Jun 21 11:13:01 2009
New Revision: 1025
Modified:
trunk/src/com/google/inject/binder/LinkedBindingBuilder.java
trunk/src/com/google/inject/internal/BindingBuilder.java
trunk/src/com/google/inject/internal/ConstructorBindingImpl.java
trunk/src/com/google/inject/spi/InjectionPoint.java
trunk/test/com/google/inject/BindingTest.java
trunk/test/com/google/inject/spi/ElementsTest.java
Log:
New API: toConstructor(Constructor, TypeLiteral).
The pair {Constructor, TypeLiteral} is necessary to specify a parameterized
constructor reference (like "new HashMap<Integer, String>()")
Modified: trunk/src/com/google/inject/binder/LinkedBindingBuilder.java
==============================================================================
--- trunk/src/com/google/inject/binder/LinkedBindingBuilder.java
(original)
+++ trunk/src/com/google/inject/binder/LinkedBindingBuilder.java Sun Jun
21
11:13:01 2009
@@ -78,5 +78,11 @@
/**
* See the EDSL examples at {...@link com.google.inject.Binder}.
*/
- ScopedBindingBuilder toConstructor(Constructor<? extends T> constructor);
+ <S extends T> ScopedBindingBuilder toConstructor(Constructor<S>
constructor);
+
+ /**
+ * See the EDSL examples at {...@link com.google.inject.Binder}.
+ */
+ <S extends T> ScopedBindingBuilder toConstructor(
+ Constructor<S> constructor, TypeLiteral<? extends S> type);
}
Modified: trunk/src/com/google/inject/internal/BindingBuilder.java
==============================================================================
--- trunk/src/com/google/inject/internal/BindingBuilder.java (original)
+++ trunk/src/com/google/inject/internal/BindingBuilder.java Sun Jun 21
11:13:01 2009
@@ -130,19 +130,21 @@
return this;
}
- public ScopedBindingBuilder toConstructor(Constructor<? extends T>
constructor) {
+ public <S extends T> ScopedBindingBuilder toConstructor(Constructor<S>
constructor) {
+ return toConstructor(constructor,
TypeLiteral.get(constructor.getDeclaringClass()));
+ }
+
+ public <S extends T> ScopedBindingBuilder toConstructor(Constructor<S>
constructor,
+ TypeLiteral<? extends S> type) {
checkNotNull(constructor, "constructor");
+ checkNotNull(type, "type");
checkNotTargetted();
BindingImpl<T> base = getBinding();
- TypeLiteral<T> keyType = base.getKey().getTypeLiteral();
- TypeLiteral<? extends T> toConstruct =
(constructor.getDeclaringClass() == keyType.getRawType())
- ? keyType
- : TypeLiteral.get(constructor.getDeclaringClass());
Set<InjectionPoint> injectionPoints;
try {
- injectionPoints =
InjectionPoint.forInstanceMethodsAndFields(toConstruct);
+ injectionPoints = InjectionPoint.forInstanceMethodsAndFields(type);
} catch (ConfigurationException e) {
copyErrorsToBinder(e);
injectionPoints = e.getPartialValue();
@@ -150,8 +152,7 @@
try {
@SuppressWarnings("unchecked") // safe; constructor is a subtype of
toConstruct
- InjectionPoint constructorPoint =
InjectionPoint.forConstructor((Constructor) constructor,
- toConstruct);
+ InjectionPoint constructorPoint =
InjectionPoint.forConstructor(constructor, type);
setBinding(new ConstructorBindingImpl<T>(base.getKey(),
base.getSource(), base.getScoping(),
constructorPoint, injectionPoints));
} catch (ConfigurationException e) {
Modified: trunk/src/com/google/inject/internal/ConstructorBindingImpl.java
==============================================================================
--- trunk/src/com/google/inject/internal/ConstructorBindingImpl.java
(original)
+++ trunk/src/com/google/inject/internal/ConstructorBindingImpl.java Sun
Jun 21 11:13:01 2009
@@ -19,16 +19,17 @@
import com.google.inject.Binder;
import com.google.inject.ConfigurationException;
import com.google.inject.Key;
-import static com.google.inject.internal.Preconditions.checkState;
+import com.google.inject.TypeLiteral;
import static com.google.inject.internal.Annotations.findScopeAnnotation;
+import static com.google.inject.internal.Preconditions.checkState;
import com.google.inject.spi.BindingTargetVisitor;
import com.google.inject.spi.ConstructorBinding;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.InjectionPoint;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -153,8 +154,9 @@
}
public void applyTo(Binder binder) {
- getScoping().applyTo(binder.withSource(getSource())
- .bind(getKey()).toConstructor((Constructor)
getConstructor().getMember()));
+ InjectionPoint constructor = getConstructor();
+
getScoping().applyTo(binder.withSource(getSource()).bind(getKey()).toConstructor(
+ (Constructor) getConstructor().getMember(), (TypeLiteral)
constructor.getDeclaringType()));
}
@Override public String toString() {
Modified: trunk/src/com/google/inject/spi/InjectionPoint.java
==============================================================================
--- trunk/src/com/google/inject/spi/InjectionPoint.java (original)
+++ trunk/src/com/google/inject/spi/InjectionPoint.java Sun Jun 21 11:13:01
2009
@@ -88,6 +88,8 @@
Key<?> key = null;
try {
key = Annotations.getKey(declaringType.getFieldType(field), field,
annotations, errors);
+ } catch (ConfigurationException e) {
+ errors.merge(e.getErrorMessages());
} catch (ErrorsException e) {
errors.merge(e.getErrors());
}
@@ -111,6 +113,8 @@
Key<?> key = Annotations.getKey(parameterType, member,
parameterAnnotations, errors);
dependencies.add(newDependency(key,
Nullability.allowsNull(parameterAnnotations), index));
index++;
+ } catch (ConfigurationException e) {
+ errors.merge(e.getErrorMessages());
} catch (ErrorsException e) {
errors.merge(e.getErrors());
}
Modified: trunk/test/com/google/inject/BindingTest.java
==============================================================================
--- trunk/test/com/google/inject/BindingTest.java (original)
+++ trunk/test/com/google/inject/BindingTest.java Sun Jun 21 11:13:01 2009
@@ -216,38 +216,59 @@
@Inject TooManyConstructors() {}
}
- public void testToConstructorBindings() throws NoSuchMethodException {
- final Constructor constructor = C.class.getConstructor(Stage.class,
Object.class);
+ public void testToConstructorBinding() throws NoSuchMethodException {
+ final Constructor<D> constructor = D.class.getConstructor(Stage.class);
Injector injector = Guice.createInjector(new AbstractModule() {
protected void configure() {
- bind(new TypeLiteral<C<Stage>>() {}).toConstructor(constructor);
- bind(new TypeLiteral<C<Injector>>() {}).toConstructor(constructor);
+ bind(Object.class).toConstructor(constructor);
}
});
- C<Stage> one = injector.getInstance(new Key<C<Stage>>() {});
+ D d = (D) injector.getInstance(Object.class);
+ assertEquals(Stage.DEVELOPMENT, d.stage);
+ }
+
+ public void testToConstructorBindingsOnParameterizedTypes() throws
NoSuchMethodException {
+ final Constructor<C> constructor = C.class.getConstructor(Stage.class,
Object.class);
+ final Key<Object> s = new Key<Object>(named("s")) {};
+ final Key<Object> i = new Key<Object>(named("i")) {};
+
+ Injector injector = Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bind(s).toConstructor(constructor, new TypeLiteral<C<Stage>>() {});
+ bind(i).toConstructor(constructor, new TypeLiteral<C<Injector>>()
{});
+ }
+ });
+
+ C<Stage> one = (C<Stage>) injector.getInstance(s);
assertEquals(Stage.DEVELOPMENT, one.stage);
assertEquals(Stage.DEVELOPMENT, one.t);
assertEquals(Stage.DEVELOPMENT, one.anotherT);
- C<Injector> two = injector.getInstance(new Key<C<Injector>>() {});
+ C<Injector> two = (C<Injector>) injector.getInstance(i);
assertEquals(Stage.DEVELOPMENT, two.stage);
assertEquals(injector, two.t);
assertEquals(injector, two.anotherT);
}
- public void testToConstructorBinding() throws NoSuchMethodException {
- final Constructor<D> constructor = D.class.getConstructor(Stage.class);
-
- Injector injector = Guice.createInjector(new AbstractModule() {
- protected void configure() {
- bind(Object.class).toConstructor(constructor);
- }
- });
+ public void testToConstructorBindingsFailsOnRawTypes() throws
NoSuchMethodException {
+ final Constructor constructor = C.class.getConstructor(Stage.class,
Object.class);
- D d = (D) injector.getInstance(Object.class);
- assertEquals(Stage.DEVELOPMENT, d.stage);
+ try {
+ Guice.createInjector(new AbstractModule() {
+ protected void configure() {
+ bind(Object.class).toConstructor(constructor);
+ }
+ });
+ fail();
+ } catch (CreationException expected) {
+ assertContains(expected.getMessage(),
+ "1) T cannot be used as a key; It is not fully specified.",
+ "at " + C.class.getName() + ".<init>(BindingTest.java:",
+ "2) T cannot be used as a key; It is not fully specified.",
+ "at " + C.class.getName() + ".anotherT(BindingTest.java:");
+ }
}
public void testToConstructorAndMethodInterceptors() throws
NoSuchMethodException {
Modified: trunk/test/com/google/inject/spi/ElementsTest.java
==============================================================================
--- trunk/test/com/google/inject/spi/ElementsTest.java (original)
+++ trunk/test/com/google/inject/spi/ElementsTest.java Sun Jun 21 11:13:01
2009
@@ -1080,20 +1080,37 @@
}
public void testBindToConstructor() throws NoSuchMethodException,
NoSuchFieldException {
- final Constructor<B> constructor =
B.class.getDeclaredConstructor(Object.class);
+ final Constructor<A> aConstructor = A.class.getDeclaredConstructor();
+ final Constructor<B> bConstructor =
B.class.getDeclaredConstructor(Object.class);
final Field field = B.class.getDeclaredField("stage");
checkModule(
new AbstractModule() {
protected void configure() {
- bind(new TypeLiteral<B<Integer>>()
{}).toConstructor((Constructor) constructor)
+ bind(A.class).toConstructor(aConstructor);
+ bind(B.class).toConstructor(bConstructor, new
TypeLiteral<B<Integer>>() {})
.in(Singleton.class);
}
},
new FailingElementVisitor() {
@Override public <T> Void visit(Binding<T> binding) {
- assertEquals(new Key<B<Integer>>() {}, binding.getKey());
+ assertEquals(new Key<A>() {}, binding.getKey());
+
+ return binding.acceptTargetVisitor(new
FailingTargetVisitor<T>() {
+ @Override public Void visit(ConstructorBinding<? extends T>
constructorBinding) {
+ InjectionPoint injectionPoint =
constructorBinding.getConstructor();
+ assertEquals(aConstructor, injectionPoint.getMember());
+ assertEquals(new TypeLiteral<A>() {},
injectionPoint.getDeclaringType());
+ return null;
+ }
+ });
+ }
+ },
+
+ new FailingElementVisitor() {
+ @Override public <T> Void visit(Binding<T> binding) {
+ assertEquals(new Key<B>() {}, binding.getKey());
binding.acceptScopingVisitor(new
FailingBindingScopingVisitor() {
@Override public Void visitScopeAnnotation(Class<? extends
Annotation> annotation) {
assertEquals(Singleton.class, annotation);
@@ -1103,7 +1120,7 @@
binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
@Override public Void visit(ConstructorBinding<? extends T>
constructorBinding) {
- assertEquals(constructor,
constructorBinding.getConstructor().getMember());
+ assertEquals(bConstructor,
constructorBinding.getConstructor().getMember());
assertEquals(Key.get(Integer.class),
getOnlyElement(constructorBinding.getConstructor().getDependencies()).getKey());
assertEquals(field,
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---