• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.inject;
18 
19 import static com.google.common.collect.ImmutableSet.of;
20 import static com.google.inject.Asserts.assertContains;
21 import static com.google.inject.JitBindingsTest.GetBindingCheck.ALLOW_BINDING;
22 import static com.google.inject.JitBindingsTest.GetBindingCheck.FAIL_ALL;
23 
24 import junit.framework.TestCase;
25 
26 import java.util.Set;
27 
28 /**
29  * Some tests for {@link Binder#requireExplicitBindings()}
30  *
31  * @author sberlin@gmail.com (Sam Berlin)
32  */
33 public class JitBindingsTest extends TestCase {
34 
jitFailed(Class<?> clazz)35   private String jitFailed(Class<?> clazz) {
36     return jitFailed(TypeLiteral.get(clazz));
37   }
38 
jitFailed(TypeLiteral<?> clazz)39   private String jitFailed(TypeLiteral<?> clazz) {
40     return "Explicit bindings are required and " + clazz + " is not explicitly bound.";
41   }
42 
jitInParentFailed(Class<?> clazz)43   private String jitInParentFailed(Class<?> clazz) {
44     return jitInParentFailed(TypeLiteral.get(clazz));
45   }
46 
jitInParentFailed(TypeLiteral<?> clazz)47   private String jitInParentFailed(TypeLiteral<?> clazz) {
48     return "Explicit bindings are required and " + clazz + " would be bound in a parent injector.";
49   }
50 
inChildMessage(Class<?> clazz)51   private String inChildMessage(Class<?> clazz) {
52     return "Unable to create binding for "
53         + clazz.getName()
54         + ". It was already configured on one or more child injectors or private modules";
55   }
56 
testLinkedBindingWorks()57   public void testLinkedBindingWorks() {
58     Injector injector = Guice.createInjector(new AbstractModule() {
59       @Override
60       protected void configure() {
61         binder().requireExplicitBindings();
62         bind(Foo.class).to(FooImpl.class);
63       }
64     });
65     // Foo was explicitly bound
66     ensureWorks(injector, Foo.class);
67     // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
68     // It is OK to call getBinding for introspection, but an error to get the provider
69     // of the binding
70     ensureFails(injector, ALLOW_BINDING, FooImpl.class);
71   }
72 
testMoreBasicsWork()73   public void testMoreBasicsWork() {
74     Injector injector = Guice.createInjector(new AbstractModule() {
75       @Override
76       protected void configure() {
77         binder().requireExplicitBindings();
78         bind(Foo.class).to(FooImpl.class);
79         bind(Bar.class);
80         bind(FooBar.class);
81       }
82     });
83     // Foo, Bar & FooBar was explicitly bound
84     ensureWorks(injector, FooBar.class, Bar.class, Foo.class);
85     // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
86     // It is OK to call getBinding for introspection, but an error to get the provider
87     // of the binding
88     ensureFails(injector, ALLOW_BINDING,  FooImpl.class);
89   }
90 
testLinkedEagerSingleton()91   public void testLinkedEagerSingleton() {
92     Injector injector = Guice.createInjector(new AbstractModule() {
93       @Override
94       protected void configure() {
95         binder().requireExplicitBindings();
96         bind(Foo.class).to(FooImpl.class).asEagerSingleton();
97       }
98     });
99     // Foo was explicitly bound
100     ensureWorks(injector, Foo.class);
101     // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
102     // It is OK to call getBinding for introspection, but an error to get the provider
103     // of the binding
104     ensureFails(injector, ALLOW_BINDING, FooImpl.class);
105   }
106 
testBasicsWithEagerSingleton()107   public void testBasicsWithEagerSingleton() {
108     Injector injector = Guice.createInjector(new AbstractModule() {
109       @Override
110       protected void configure() {
111         binder().requireExplicitBindings();
112         bind(Foo.class).to(FooImpl.class).asEagerSingleton();
113         bind(Bar.class);
114         bind(FooBar.class);
115       }
116     });
117     // Foo, Bar & FooBar was explicitly bound
118     ensureWorks(injector, FooBar.class, Bar.class, Foo.class);
119     // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
120     // It is OK to call getBinding for introspection, but an error to get the provider
121     // of the binding
122     ensureFails(injector, ALLOW_BINDING,  FooImpl.class);
123   }
124 
testLinkedToScoped()125   public void testLinkedToScoped() {
126     Injector injector = Guice.createInjector(new AbstractModule() {
127       @Override
128       protected void configure() {
129         binder.requireExplicitBindings();
130         bind(Foo.class).to(ScopedFooImpl.class);
131       }
132     });
133     // Foo was explicitly bound
134     ensureWorks(injector, Foo.class);
135     // FooSingletonImpl was implicitly bound, it is an error to call getInstance or getProvider,
136     // It is OK to call getBinding for introspection, but an error to get the provider
137     // of the binding
138     ensureFails(injector, ALLOW_BINDING, ScopedFooImpl.class);
139   }
140 
testBasicsWithScoped()141   public void testBasicsWithScoped() {
142     Injector injector = Guice.createInjector(new AbstractModule() {
143       @Override
144       protected void configure() {
145         binder().requireExplicitBindings();
146         bind(Foo.class).to(ScopedFooImpl.class);
147         bind(Bar.class);
148         bind(FooBar.class);
149       }
150     });
151     // Foo, Bar & FooBar was explicitly bound
152     ensureWorks(injector, FooBar.class, Bar.class, Foo.class);
153     // FooSingletonImpl was implicitly bound, it is an error to call getInstance or getProvider,
154     // It is OK to call getBinding for introspection, but an error to get the provider
155     // of the binding
156     ensureFails(injector, ALLOW_BINDING,  ScopedFooImpl.class);
157   }
158 
testFailsIfInjectingScopedDirectlyWhenItIsntBound()159   public void testFailsIfInjectingScopedDirectlyWhenItIsntBound() {
160     try {
161       Guice.createInjector(new AbstractModule() {
162         @Override
163         protected void configure() {
164           binder().requireExplicitBindings();
165           bind(Foo.class).to(ScopedFooImpl.class);
166           bind(WantsScopedFooImpl.class);
167         }
168       });
169       fail();
170     } catch(CreationException expected) {
171       assertContains(expected.getMessage(), jitFailed(ScopedFooImpl.class));
172       assertEquals(1, expected.getErrorMessages().size());
173     }
174   }
175 
testLinkedProviderBindingWorks()176   public void testLinkedProviderBindingWorks() {
177     Injector injector = Guice.createInjector(new AbstractModule() {
178       @Override
179       protected void configure() {
180         binder().requireExplicitBindings();
181         bind(Foo.class).toProvider(FooProvider.class);
182       }
183     });
184     // Foo was explicitly bound
185     ensureWorks(injector, Foo.class);
186     // FooImpl was not bound at all (even implicitly), it is an error
187     // to call getInstance, getProvider, or getBinding.
188     ensureFails(injector, FAIL_ALL, FooImpl.class);
189   }
190 
testJitGetFails()191   public void testJitGetFails() {
192     try {
193       Guice.createInjector(new AbstractModule() {
194         @Override
195         protected void configure() {
196          binder().requireExplicitBindings();
197         }
198       }).getInstance(Bar.class);
199       fail("should have failed");
200     } catch(ConfigurationException expected) {
201       assertContains(expected.getMessage(), jitFailed(Bar.class));
202       assertEquals(1, expected.getErrorMessages().size());
203     }
204   }
205 
testJitInjectionFails()206   public void testJitInjectionFails() {
207     try {
208       Guice.createInjector(new AbstractModule() {
209         @Override
210         protected void configure() {
211           binder().requireExplicitBindings();
212           bind(Foo.class).to(FooImpl.class);
213           bind(FooBar.class);
214         }
215       });
216       fail("should have failed");
217     } catch (CreationException expected) {
218       assertContains(expected.getMessage(), jitFailed(Bar.class));
219       assertEquals(1, expected.getErrorMessages().size());
220     }
221   }
222 
testJitProviderGetFails()223   public void testJitProviderGetFails() {
224     try {
225       Guice.createInjector(new AbstractModule() {
226         @Override
227         protected void configure() {
228           binder().requireExplicitBindings();
229         }
230       }).getProvider(Bar.class);
231       fail("should have failed");
232     } catch (ConfigurationException expected) {
233       assertContains(expected.getMessage(), jitFailed(Bar.class));
234       assertEquals(1, expected.getErrorMessages().size());
235     }
236   }
237 
testJitProviderInjectionFails()238   public void testJitProviderInjectionFails() {
239     try {
240       Guice.createInjector(new AbstractModule() {
241         @Override
242         protected void configure() {
243           binder().requireExplicitBindings();
244           bind(Foo.class).to(FooImpl.class);
245           bind(ProviderFooBar.class);
246         }
247       });
248       fail("should have failed");
249     } catch (CreationException expected) {
250       assertContains(expected.getMessage(), jitFailed(Bar.class));
251       assertEquals(1, expected.getErrorMessages().size());
252     }
253   }
254 
testImplementedBy()255   public void testImplementedBy() {
256     Injector injector = Guice.createInjector(new AbstractModule() {
257       @Override
258       protected void configure() {
259         binder().requireExplicitBindings();
260         bind(ImplBy.class);
261       }
262     });
263     ensureWorks(injector, ImplBy.class);
264     ensureFails(injector, ALLOW_BINDING, ImplByImpl.class);
265   }
266 
testImplementedBySomethingThatIsAnnotated()267   public void testImplementedBySomethingThatIsAnnotated() {
268     Injector injector = Guice.createInjector(new AbstractModule() {
269       @Override
270       protected void configure() {
271         binder().requireExplicitBindings();
272         bind(ImplByScoped.class);
273       }
274     });
275     ensureWorks(injector, ImplByScoped.class);
276     ensureFails(injector, ALLOW_BINDING, ImplByScopedImpl.class);
277   }
278 
testProvidedBy()279   public void testProvidedBy() {
280     Injector injector = Guice.createInjector(new AbstractModule() {
281       @Override
282       protected void configure() {
283         binder().requireExplicitBindings();
284         bind(ProvBy.class);
285       }
286     });
287     ensureWorks(injector, ProvBy.class);
288     ensureFails(injector, ALLOW_BINDING, ProvByProvider.class);
289   }
290 
testProviderMethods()291   public void testProviderMethods() {
292     Injector injector = Guice.createInjector(new AbstractModule() {
293       @Override protected void configure() {
294         binder().requireExplicitBindings();
295       }
296       @SuppressWarnings("unused") @Provides Foo foo() { return new FooImpl(); }
297     });
298     ensureWorks(injector, Foo.class);
299   }
300 
testChildInjectorInheritsOption()301   public void testChildInjectorInheritsOption() {
302     Injector parent = Guice.createInjector(new AbstractModule() {
303       @Override
304       protected void configure() {
305         binder().requireExplicitBindings();
306         bind(Bar.class);
307       }
308     });
309     ensureWorks(parent, Bar.class);
310     ensureFails(parent, FAIL_ALL, FooImpl.class, FooBar.class, Foo.class);
311 
312     try {
313       parent.createChildInjector(new AbstractModule() {
314         @Override
315         protected void configure() {
316           bind(FooBar.class);
317         }
318       });
319       fail("should have failed");
320     } catch(CreationException expected) {
321       assertContains(expected.getMessage(), jitFailed(Foo.class));
322       assertEquals(1, expected.getErrorMessages().size());
323     }
324 
325     Injector child = parent.createChildInjector(new AbstractModule() {
326       @Override
327       protected void configure() {
328         bind(Foo.class).to(FooImpl.class);
329       }
330     });
331     ensureWorks(child, Foo.class, Bar.class);
332     ensureFails(child, ALLOW_BINDING, FooImpl.class);
333     ensureInChild(parent, FooImpl.class, Foo.class);
334     // TODO(sameb): FooBar may or may not be in a child injector, depending on if GC has run.
335     // We should fix failed child injectors to remove their contents from the parent blacklist
336     // immediately, rather than waiting on GC to do it.
337     // FooBar was succesfully inserted into the child injector (and parent blacklist), but then
338     // JIT bindings it depended on failed, making the child injector invalid.
339 
340     Injector grandchild = child.createChildInjector(new AbstractModule() {
341       @Override
342       protected void configure() {
343         bind(FooBar.class);
344       }
345     });
346     ensureWorks(grandchild, FooBar.class, Foo.class, Bar.class);
347     ensureFails(grandchild, ALLOW_BINDING, FooImpl.class);
348     ensureFails(child, ALLOW_BINDING, FooImpl.class);
349     ensureInChild(parent, FooImpl.class, FooBar.class, Foo.class);
350   }
351 
testChildInjectorAddsOption()352   public void testChildInjectorAddsOption() {
353     Injector parent = Guice.createInjector(new AbstractModule() {
354       @Override
355       protected void configure() {
356         bind(Bar.class);
357       }
358     });
359     int totalParentBindings = parent.getAllBindings().size();
360 
361     try {
362       parent.createChildInjector(new AbstractModule() {
363         @Override
364         protected void configure() {
365           binder().requireExplicitBindings();
366           bind(FooBar.class);
367         }
368       });
369       fail("should have failed");
370     } catch(CreationException expected) {
371       assertContains(expected.getMessage(), jitFailed(Foo.class));
372       assertEquals(1, expected.getErrorMessages().size());
373     }
374     assertEquals(totalParentBindings, parent.getAllBindings().size());
375 
376     Injector child = parent.createChildInjector(new AbstractModule() {
377       @Override
378       protected void configure() {
379         binder().requireExplicitBindings();
380         bind(Foo.class).to(FooImpl.class);
381         bind(FooImpl.class);
382       }
383     });
384     assertEquals(totalParentBindings, parent.getAllBindings().size());
385     ensureWorks(child, Foo.class, Bar.class);
386 
387     Injector grandchild = child.createChildInjector(new AbstractModule() {
388       @Override
389       protected void configure() {
390         bind(FooBar.class);
391       }
392     });
393     assertEquals(totalParentBindings, parent.getAllBindings().size());
394     ensureWorks(grandchild, FooBar.class, Foo.class, Bar.class);
395 
396     // Make sure siblings of children don't inherit each others settings...
397     // a new child should be able to get FooImpl.
398     child = parent.createChildInjector();
399     ensureWorks(child, FooImpl.class);
400   }
401 
testPrivateModulesInheritOptions()402   public void testPrivateModulesInheritOptions() {
403     try {
404       Guice.createInjector(new AbstractModule() {
405         protected void configure() {
406           binder().requireExplicitBindings();
407           bind(Foo.class).to(FooImpl.class);
408 
409           install(new PrivateModule() {
410             public void configure() {
411               bind(FooBar.class);
412               expose(FooBar.class);
413             }
414           });
415         }
416       });
417       fail("should have failed");
418     } catch(CreationException expected) {
419       assertContains(expected.getMessage(), jitFailed(Bar.class));
420       assertEquals(1, expected.getErrorMessages().size());
421     }
422 
423     Injector injector = Guice.createInjector(new AbstractModule() {
424       protected void configure() {
425         binder().requireExplicitBindings();
426 
427         install(new PrivateModule() {
428           public void configure() {
429             bind(Foo.class).to(FooImpl.class);
430             expose(Foo.class);
431           }
432         });
433       }
434     });
435     ensureInChild(injector, FooImpl.class);
436   }
437 
testPrivateModuleAddsOption()438   public void testPrivateModuleAddsOption() {
439     try {
440       Guice.createInjector(new AbstractModule() {
441         protected void configure() {
442           bind(Foo.class).to(FooImpl.class);
443 
444           // Fails because FooBar is in the private module,
445           // and it wants Bar, but Bar would be JIT.
446           install(new PrivateModule() {
447             public void configure() {
448               binder().requireExplicitBindings();
449               bind(FooBar.class);
450               expose(FooBar.class);
451             }
452           });
453         }
454       });
455       fail("should have failed");
456     } catch(CreationException expected) {
457       assertContains(expected.getMessage(), jitFailed(Bar.class));
458       assertEquals(1, expected.getErrorMessages().size());
459     }
460   }
461 
testPrivateModuleSiblingsDontShareOption()462   public void testPrivateModuleSiblingsDontShareOption() {
463     Guice.createInjector(new AbstractModule() {
464       protected void configure() {
465         bind(Foo.class).to(FooImpl.class);
466 
467         install(new PrivateModule() {
468           public void configure() {
469             binder().requireExplicitBindings();
470           }
471         });
472 
473         // This works, even though Bar is JIT,
474         // because the requireExplicitBindings isn't shared
475         // between sibling private modules.
476         install(new PrivateModule() {
477           public void configure() {
478             bind(FooBar.class);
479             expose(FooBar.class);
480           }
481         });
482       }
483     });
484   }
485 
testTypeLiteralsCanBeInjected()486   public void testTypeLiteralsCanBeInjected() {
487     Injector injector = Guice.createInjector(new AbstractModule() {
488         @Override protected void configure() {
489           binder().requireExplicitBindings();
490           bind(new TypeLiteral<WantsTypeLiterals<String>>() {});
491           bind(new TypeLiteral<Set<String>>() {}).toInstance(of("bar"));
492         }
493       });
494 
495     WantsTypeLiterals<String> foo = injector.getInstance(new Key<WantsTypeLiterals<String>>() {});
496     assertEquals(foo.literal.getRawType(), String.class);
497     assertEquals(of("bar"), foo.set);
498   }
499 
testMembersInjectorsCanBeInjected()500   public void testMembersInjectorsCanBeInjected() {
501     Injector injector = Guice.createInjector(new AbstractModule() {
502       @Override protected void configure() {
503         binder().requireExplicitBindings();
504       }
505 
506       @Provides String data(MembersInjector<String> mi) {
507         String data = "foo";
508         mi.injectMembers(data);
509         return data;
510       }
511     });
512 
513     String data = injector.getInstance(String.class);
514     assertEquals("foo", data);
515   }
516 
testJitLinkedBindingInParentFails()517   public void testJitLinkedBindingInParentFails() {
518     try {
519       Guice.createInjector(new AbstractModule() {
520         @Override
521         protected void configure() {
522           install(new PrivateModule() {
523             @Override
524             protected void configure() {
525               binder().requireExplicitBindings();
526               bind(Foo.class).to(FooImpl.class);
527             }
528           });
529         }
530       });
531       fail("should have failed");
532     } catch (CreationException expected) {
533       assertContains(expected.getMessage(), jitInParentFailed(FooImpl.class));
534       assertEquals(1, expected.getErrorMessages().size());
535     }
536   }
537 
testJitProviderBindingInParentFails()538   public void testJitProviderBindingInParentFails() {
539     try {
540       Guice.createInjector(new AbstractModule() {
541         @Override
542         protected void configure() {
543           install(new PrivateModule() {
544             @Override
545             protected void configure() {
546               binder().requireExplicitBindings();
547               bind(Foo.class).toProvider(FooProvider.class);
548             }
549           });
550         }
551       });
552       fail("should have failed");
553     } catch (CreationException expected) {
554       assertContains(expected.getMessage(), jitInParentFailed(FooProvider.class));
555       assertEquals(1, expected.getErrorMessages().size());
556     }
557   }
558 
testJitImplementedByBindingInParentFails()559   public void testJitImplementedByBindingInParentFails() {
560     try {
561       Guice.createInjector(new AbstractModule() {
562         @Override
563         protected void configure() {
564           install(new PrivateModule() {
565             @Override
566             protected void configure() {
567               binder().requireExplicitBindings();
568               bind(ImplBy.class);
569             }
570           });
571         }
572       });
573       fail("should have failed");
574     } catch (CreationException expected) {
575       assertContains(expected.getMessage(), jitInParentFailed(ImplByImpl.class));
576       assertEquals(1, expected.getErrorMessages().size());
577     }
578   }
579 
testJitProvidedByBindingInParentFails()580   public void testJitProvidedByBindingInParentFails() {
581     try {
582       Guice.createInjector(new AbstractModule() {
583         @Override
584         protected void configure() {
585           install(new PrivateModule() {
586             @Override
587             protected void configure() {
588               binder().requireExplicitBindings();
589               bind(ProvBy.class);
590             }
591           });
592         }
593       });
594       fail("should have failed");
595     } catch (CreationException expected) {
596       assertContains(expected.getMessage(), jitInParentFailed(ProvByProvider.class));
597       assertEquals(1, expected.getErrorMessages().size());
598     }
599   }
600 
ensureWorks(Injector injector, Class<?>... classes)601   private void ensureWorks(Injector injector, Class<?>... classes) {
602     for(int i = 0; i < classes.length; i++) {
603       injector.getInstance(classes[i]);
604       injector.getProvider(classes[i]).get();
605       injector.getBinding(classes[i]).getProvider().get();
606     }
607   }
608 
609   enum GetBindingCheck { FAIL_ALL, ALLOW_BINDING, ALLOW_BINDING_PROVIDER }
ensureFails(Injector injector, GetBindingCheck getBinding, Class<?>... classes)610   private void ensureFails(Injector injector, GetBindingCheck getBinding, Class<?>... classes) {
611     for(int i = 0; i < classes.length; i++) {
612       try {
613         injector.getInstance(classes[i]);
614         fail("should have failed tring to retrieve class: " + classes[i]);
615       } catch(ConfigurationException expected) {
616         assertContains(expected.getMessage(), jitFailed(classes[i]));
617         assertEquals(1, expected.getErrorMessages().size());
618       }
619 
620       try {
621         injector.getProvider(classes[i]);
622         fail("should have failed tring to retrieve class: " + classes[i]);
623       } catch(ConfigurationException expected) {
624         assertContains(expected.getMessage(), jitFailed(classes[i]));
625         assertEquals(1, expected.getErrorMessages().size());
626       }
627 
628       if (getBinding == GetBindingCheck.ALLOW_BINDING
629           || getBinding == GetBindingCheck.ALLOW_BINDING_PROVIDER) {
630         Binding<?> binding = injector.getBinding(classes[i]);
631         try {
632           binding.getProvider();
633           if (getBinding != GetBindingCheck.ALLOW_BINDING_PROVIDER) {
634             fail("should have failed trying to retrieve class: " + classes[i]);
635           }
636         } catch(ConfigurationException expected) {
637           if (getBinding == GetBindingCheck.ALLOW_BINDING_PROVIDER) {
638             throw expected;
639           }
640           assertContains(expected.getMessage(), jitFailed(classes[i]));
641           assertEquals(1, expected.getErrorMessages().size());
642         }
643       } else {
644         try {
645           injector.getBinding(classes[i]);
646           fail("should have failed tring to retrieve class: " + classes[i]);
647         } catch(ConfigurationException expected) {
648           assertContains(expected.getMessage(), jitFailed(classes[i]));
649           assertEquals(1, expected.getErrorMessages().size());
650         }
651       }
652     }
653   }
654 
ensureInChild(Injector injector, Class<?>... classes)655   private void ensureInChild(Injector injector, Class<?>... classes) {
656     for(int i = 0; i < classes.length; i++) {
657       try {
658         injector.getInstance(classes[i]);
659         fail("should have failed tring to retrieve class: " + classes[i]);
660       } catch(ConfigurationException expected) {
661         assertContains(expected.getMessage(), inChildMessage(classes[i]));
662         assertEquals(1, expected.getErrorMessages().size());
663       }
664 
665       try {
666         injector.getProvider(classes[i]);
667         fail("should have failed tring to retrieve class: " + classes[i]);
668       } catch(ConfigurationException expected) {
669         assertContains(expected.getMessage(), inChildMessage(classes[i]));
670         assertEquals(1, expected.getErrorMessages().size());
671       }
672 
673       try {
674         injector.getBinding(classes[i]);
675         fail("should have failed tring to retrieve class: " + classes[i]);
676       } catch(ConfigurationException expected) {
677         assertContains(expected.getMessage(), inChildMessage(classes[i]));
678         assertEquals(1, expected.getErrorMessages().size());
679       }
680     }
681   }
682 
683   private static interface Foo {}
684   private static class FooImpl implements Foo {}
685   @Singleton private static class ScopedFooImpl implements Foo {}
686   private static class WantsScopedFooImpl {
687     @SuppressWarnings("unused") @Inject ScopedFooImpl scopedFoo;
688   }
689   private static class Bar {}
690   private static class FooBar {
691     @SuppressWarnings("unused") @Inject Foo foo;
692     @SuppressWarnings("unused") @Inject Bar bar;
693   }
694   private static class ProviderFooBar {
695     @SuppressWarnings("unused") @Inject Provider<Foo> foo;
696     @SuppressWarnings("unused") @Inject Provider<Bar> bar;
697   }
698   private static class FooProvider implements Provider<Foo> {
get()699     public Foo get() {
700       return new FooImpl();
701     }
702   }
703 
704   @ImplementedBy(ImplByImpl.class)
705   private static interface ImplBy {}
706   private static class ImplByImpl implements ImplBy {}
707 
708   @ImplementedBy(ImplByScopedImpl.class)
709   private static interface ImplByScoped {}
710   @Singleton
711   private static class ImplByScopedImpl implements ImplByScoped {}
712 
713   @ProvidedBy(ProvByProvider.class)
714   private static interface ProvBy {}
715   private static class ProvByProvider implements Provider<ProvBy> {
get()716     public ProvBy get() {
717       return new ProvBy() {};
718     }
719   }
720 
721   private static class WantsTypeLiterals<T> {
722     TypeLiteral<T> literal;
723     Set<T> set;
724 
WantsTypeLiterals(TypeLiteral<T> literal, Set<T> set)725     @Inject WantsTypeLiterals(TypeLiteral<T> literal, Set<T> set) {
726       this.literal = literal;
727       this.set = set;
728 
729     }
730   }
731 }
732