summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2014-10-04 12:24:51 -0400
committerTavian Barnes <tavianator@tavianator.com>2014-10-04 12:24:51 -0400
commitb8c1ca531321dbcee3ae237bad20fa8691b31f83 (patch)
tree2432ad47f835af34ebdddb2306598f6d7d34c9ff
parent5a08861fcb8c5bc5831a6b99c192aba0a7933952 (diff)
downloadsangria-b8c1ca531321dbcee3ae237bad20fa8691b31f83.tar.xz
contextual: Make ContextSensitiveBinder work with requireExplicitBindings().
Same as regular toProvider() bindings, an explicit binding for the provider is *not* required, unless to provider itself is injected somewhere. This is accomplished by generating a unique linked-key binding for each ContextSensitiveProvider.
-rw-r--r--sangria-contextual/pom.xml6
-rw-r--r--sangria-contextual/src/main/java/com/tavianator/sangria/contextual/ContextSensitiveBinder.java18
-rw-r--r--sangria-contextual/src/test/java/com/tavianator/sangria/contextual/ContextSensitiveBinderTest.java21
3 files changed, 42 insertions, 3 deletions
diff --git a/sangria-contextual/pom.xml b/sangria-contextual/pom.xml
index c939076..702616f 100644
--- a/sangria-contextual/pom.xml
+++ b/sangria-contextual/pom.xml
@@ -38,6 +38,12 @@
</dependency>
<dependency>
+ <groupId>com.tavianator.sangria</groupId>
+ <artifactId>sangria-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
diff --git a/sangria-contextual/src/main/java/com/tavianator/sangria/contextual/ContextSensitiveBinder.java b/sangria-contextual/src/main/java/com/tavianator/sangria/contextual/ContextSensitiveBinder.java
index 6d5e502..fdc1ad0 100644
--- a/sangria-contextual/src/main/java/com/tavianator/sangria/contextual/ContextSensitiveBinder.java
+++ b/sangria-contextual/src/main/java/com/tavianator/sangria/contextual/ContextSensitiveBinder.java
@@ -40,6 +40,7 @@ import com.google.inject.spi.ProviderWithExtensionVisitor;
import com.google.inject.spi.ProvisionListener;
import com.tavianator.sangria.core.DelayedError;
+import com.tavianator.sangria.core.UniqueAnnotations;
/**
* A binder for {@link ContextSensitiveProvider}s.
@@ -139,10 +140,17 @@ public class ContextSensitiveBinder {
public void toContextSensitiveProvider(Key<? extends ContextSensitiveProvider<? extends T>> key) {
error.cancel();
- binder.bind(bindingKey).toProvider(new ProviderKeyAdapter<>(key));
+ binder.bind(bindingKey).toProvider(new ProviderKeyAdapter<>(key, makeLinkedKey(key)));
binder.bindListener(new BindingMatcher(bindingKey), new Trigger(bindingKey));
}
+ private <U> Key<U> makeLinkedKey(Key<U> key) {
+ Key<U> linkedKey = Key.get(key.getTypeLiteral(), UniqueAnnotations.create());
+ binder.bind(linkedKey)
+ .to(key);
+ return linkedKey;
+ }
+
@Override
public void toContextSensitiveProvider(ContextSensitiveProvider<? extends T> provider) {
error.cancel();
@@ -190,15 +198,19 @@ public class ContextSensitiveBinder {
private static class ProviderKeyAdapter<T> extends ProviderAdapter<T> implements ContextSensitiveProviderKeyBinding<T> {
private final Key<? extends ContextSensitiveProvider<? extends T>> providerKey;
+ private final Key<? extends ContextSensitiveProvider<? extends T>> linkedKey;
private Provider<? extends ContextSensitiveProvider<? extends T>> provider;
- ProviderKeyAdapter(Key<? extends ContextSensitiveProvider<? extends T>> providerKey) {
+ ProviderKeyAdapter(
+ Key<? extends ContextSensitiveProvider<? extends T>> providerKey,
+ Key<? extends ContextSensitiveProvider<? extends T>> linkedKey) {
this.providerKey = providerKey;
+ this.linkedKey = linkedKey;
}
@Inject
void inject(Injector injector) {
- provider = injector.getProvider(providerKey);
+ provider = injector.getProvider(linkedKey);
}
@Override
diff --git a/sangria-contextual/src/test/java/com/tavianator/sangria/contextual/ContextSensitiveBinderTest.java b/sangria-contextual/src/test/java/com/tavianator/sangria/contextual/ContextSensitiveBinderTest.java
index 1e2ab49..68250cb 100644
--- a/sangria-contextual/src/test/java/com/tavianator/sangria/contextual/ContextSensitiveBinderTest.java
+++ b/sangria-contextual/src/test/java/com/tavianator/sangria/contextual/ContextSensitiveBinderTest.java
@@ -28,6 +28,7 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.MembersInjector;
+import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
import com.google.inject.TypeLiteral;
@@ -40,6 +41,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import static com.tavianator.sangria.test.SangriaMatchers.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
@@ -54,6 +56,10 @@ public class ContextSensitiveBinderTest {
public @Rule ExpectedException thrown = ExpectedException.none();
private static class SelfProvider implements ContextSensitiveProvider<String> {
+ @Inject
+ SelfProvider() {
+ }
+
// For testing getInjectionPoints() in the SPI below
@SuppressWarnings("unused")
@Inject Injector injector;
@@ -191,6 +197,21 @@ public class ContextSensitiveBinderTest {
assertThat(hasSelf.selfProvider.get(), equalTo("<unknown>"));
}
+ @Test
+ public void testBestPractices() {
+ Module module = new AbstractModule() {
+ @Override
+ protected void configure() {
+ ContextSensitiveBinder.create(binder())
+ .bind(String.class)
+ .annotatedWith(Names.named("self"))
+ .toContextSensitiveProvider(SelfProvider.class);
+ }
+ };
+ assertThat(module, is(atomic()));
+ assertThat(module, followsBestPractices());
+ }
+
private static class RequiredContextProvider implements ContextSensitiveProvider<String> {
@Override
public String getInContext(InjectionPoint injectionPoint) {