blob: 1ab175771c68cb97bbc1b58f31c9c244b16080e1 [file] [log] [blame]
limpbizkite451ef72007-12-19 01:15:59 +00001/**
2 * Copyright (C) 2007 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
17package com.google.inject.assistedinject;
18
limpbizkit9532e622008-06-18 08:20:54 +000019import com.google.inject.AbstractModule;
limpbizkiteab76472008-05-26 19:45:12 +000020import static com.google.inject.Asserts.assertContains;
limpbizkitddb38622008-12-29 05:21:16 +000021import com.google.inject.Binding;
limpbizkitfcbdf992008-11-26 02:37:35 +000022import com.google.inject.ConfigurationException;
limpbizkit9532e622008-06-18 08:20:54 +000023import com.google.inject.CreationException;
24import com.google.inject.Guice;
25import com.google.inject.Inject;
26import com.google.inject.Injector;
limpbizkitddb38622008-12-29 05:21:16 +000027import com.google.inject.Key;
limpbizkit9532e622008-06-18 08:20:54 +000028import com.google.inject.Provider;
29import com.google.inject.TypeLiteral;
sberlind9c913a2011-06-26 21:02:54 +000030import com.google.common.collect.ImmutableSet;
limpbizkite451ef72007-12-19 01:15:59 +000031import com.google.inject.name.Named;
32import com.google.inject.name.Names;
limpbizkitddb38622008-12-29 05:21:16 +000033import com.google.inject.spi.Dependency;
34import com.google.inject.spi.HasDependencies;
limpbizkit9532e622008-06-18 08:20:54 +000035import java.awt.Color;
limpbizkite451ef72007-12-19 01:15:59 +000036import java.util.Collection;
37import java.util.Collections;
38import java.util.Set;
limpbizkit9532e622008-06-18 08:20:54 +000039import junit.framework.TestCase;
limpbizkite451ef72007-12-19 01:15:59 +000040
41/**
42 * @author jmourits@google.com (Jerome Mourits)
43 * @author jessewilson@google.com (Jesse Wilson)
44 */
45public class FactoryProviderTest extends TestCase {
46
47 public void testAssistedFactory() {
48 Injector injector = Guice.createInjector(new AbstractModule() {
49 @Override
50 protected void configure() {
51 bind(Double.class).toInstance(5.0d);
52 bind(ColoredCarFactory.class)
53 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
54 }
55 });
56 ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
57
58 Mustang blueMustang = (Mustang) carFactory.create(Color.BLUE);
59 assertEquals(Color.BLUE, blueMustang.color);
60 assertEquals(5.0d, blueMustang.engineSize);
61
62 Mustang redMustang = (Mustang) carFactory.create(Color.RED);
63 assertEquals(Color.RED, redMustang.color);
64 assertEquals(5.0d, redMustang.engineSize);
65 }
66
limpbizkitddb38622008-12-29 05:21:16 +000067 public void testFactoryBindingDependencies() {
68 Injector injector = Guice.createInjector(new AbstractModule() {
69 @Override
70 protected void configure() {
71 bind(Double.class).toInstance(5.0d);
72 bind(ColoredCarFactory.class)
73 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
74 }
75 });
76
77 Binding<?> binding = injector.getBinding(ColoredCarFactory.class);
78 HasDependencies hasDependencies = (HasDependencies) binding;
79 assertEquals(ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(double.class))),
80 hasDependencies.getDependencies());
81 }
82
limpbizkite451ef72007-12-19 01:15:59 +000083 public void testAssistedFactoryWithAnnotations() {
84 Injector injector = Guice.createInjector(new AbstractModule() {
85 @Override
86 protected void configure() {
87 bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
88 bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
89 bind(ColoredCarFactory.class)
90 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Camaro.class));
91 }
92 });
93
94 ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
95
96 Camaro blueCamaro = (Camaro) carFactory.create(Color.BLUE);
97 assertEquals(Color.BLUE, blueCamaro.color);
98 assertEquals(1984, blueCamaro.modelYear);
99 assertEquals(250, blueCamaro.horsePower);
100
101 Camaro redCamaro = (Camaro) carFactory.create(Color.RED);
102 assertEquals(Color.RED, redCamaro.color);
103 assertEquals(1984, redCamaro.modelYear);
104 assertEquals(250, redCamaro.horsePower);
105 }
106
107 interface Car {
108 }
109
110 interface ColoredCarFactory {
111 Car create(Color color);
112 }
113
114 public static class Mustang implements Car {
115 private final double engineSize;
116 private final Color color;
117
118 @AssistedInject
119 public Mustang(double engineSize, @Assisted Color color) {
120 this.engineSize = engineSize;
121 this.color = color;
122 }
123 }
124
125 public static class Camaro implements Car {
126 private final int horsePower;
127 private final int modelYear;
128 private final Color color;
129
130 @AssistedInject
131 public Camaro(
132 @Named("horsePower")int horsePower,
133 @Named("modelYear")int modelYear,
134 @Assisted Color color) {
135 this.horsePower = horsePower;
136 this.modelYear = modelYear;
137 this.color = color;
138 }
139 }
140
141 interface SummerCarFactory {
142 Car create(Color color, boolean convertable);
143 Car createConvertible(Color color);
144 }
145
146 public void testFactoryWithMultipleMethods() {
147 Injector injector = Guice.createInjector(new AbstractModule() {
148 @Override
149 protected void configure() {
150 bind(float.class).toInstance(140f);
151 bind(SummerCarFactory.class).toProvider(
152 FactoryProvider.newFactory(SummerCarFactory.class, Corvette.class));
153 }
154 });
155
156 SummerCarFactory carFactory = injector.getInstance(SummerCarFactory.class);
157
158 Corvette blueCorvette = (Corvette) carFactory.createConvertible(Color.BLUE);
159 assertEquals(Color.BLUE, blueCorvette.color);
160 assertEquals(100f, blueCorvette.maxMph);
161 assertTrue(blueCorvette.isConvertable);
162
163 Corvette redCorvette = (Corvette) carFactory.create(Color.RED, false);
164 assertEquals(Color.RED, redCorvette.color);
165 assertEquals(140f, redCorvette.maxMph);
166 assertFalse(redCorvette.isConvertable);
167 }
168
169 public static class Corvette implements Car {
170 private boolean isConvertable;
171 private Color color;
172 private float maxMph;
173
174 @AssistedInject
175 public Corvette(@Assisted Color color) {
176 this(color, 100f, true);
177 }
178
179 public Corvette(@Assisted Color color, @Assisted boolean isConvertable) {
180 throw new IllegalStateException("Not an @AssistedInject constructor");
181 }
182
183 @AssistedInject
184 public Corvette(@Assisted Color color, Float maxMph, @Assisted boolean isConvertable) {
185 this.isConvertable = isConvertable;
186 this.color = color;
187 this.maxMph = maxMph;
188 }
189 }
190
191 public void testFactoryMethodsMismatch() {
192 try {
193 FactoryProvider.newFactory(SummerCarFactory.class, Beetle.class);
194 fail();
limpbizkitfcbdf992008-11-26 02:37:35 +0000195 } catch(ConfigurationException e) {
196 assertContains(e.getMessage(), "Constructor mismatch");
limpbizkite451ef72007-12-19 01:15:59 +0000197 }
198 }
199
200 public static class Beetle implements Car {
201 @AssistedInject
202 public Beetle(@Assisted Color color) {
203 throw new IllegalStateException("Conflicting constructors");
204 }
205 @AssistedInject
206 public Beetle(@Assisted Color color, @Assisted boolean isConvertable) {
207 throw new IllegalStateException("Conflicting constructors");
208 }
209 @AssistedInject
210 public Beetle(@Assisted Color color, @Assisted boolean isConvertable, float maxMph) {
211 throw new IllegalStateException("Conflicting constructors");
212 }
213 }
214
215 public void testMethodsAndFieldsGetInjected() {
216 Injector injector = Guice.createInjector(new AbstractModule() {
217 @Override
218 protected void configure() {
219 bind(String.class).toInstance("turbo");
220 bind(int.class).toInstance(911);
221 bind(double.class).toInstance(50000d);
222 bind(ColoredCarFactory.class)
223 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Porshe.class));
224 }
225 });
226 ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
227
228 Porshe grayPorshe = (Porshe) carFactory.create(Color.GRAY);
229 assertEquals(Color.GRAY, grayPorshe.color);
230 assertEquals(50000d, grayPorshe.price);
231 assertEquals(911, grayPorshe.model);
232 assertEquals("turbo", grayPorshe.name);
233 }
234
235 public static class Porshe implements Car {
236 private final Color color;
237 private final double price;
238 private @Inject String name;
239 private int model;
240
241 @AssistedInject
242 public Porshe(@Assisted Color color, double price) {
243 this.color = color;
244 this.price = price;
245 }
246
247 @Inject void setModel(int model) {
248 this.model = model;
249 }
250 }
251
252 public void testProviderInjection() {
253 Injector injector = Guice.createInjector(new AbstractModule() {
254 @Override
255 protected void configure() {
256 bind(String.class).toInstance("trans am");
257 bind(ColoredCarFactory.class)
258 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Firebird.class));
259 }
260 });
261 ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
262
263 Firebird blackFirebird = (Firebird) carFactory.create(Color.BLACK);
264 assertEquals(Color.BLACK, blackFirebird.color);
265 assertEquals("trans am", blackFirebird.modifiersProvider.get());
266 }
267
268 public static class Firebird implements Car {
269 private final Provider<String> modifiersProvider;
270 private final Color color;
271
272 @AssistedInject
273 public Firebird(Provider<String> modifiersProvider, @Assisted Color color) {
274 this.modifiersProvider = modifiersProvider;
275 this.color = color;
276 }
277 }
278
279 public void testTypeTokenInjection() {
280 Injector injector = Guice.createInjector(new AbstractModule() {
281 @Override
282 protected void configure() {
283 bind(new TypeLiteral<Set<String>>() {}).toInstance(Collections.singleton("Flux Capacitor"));
284 bind(new TypeLiteral<Set<Integer>>() {}).toInstance(Collections.singleton(88));
285 bind(ColoredCarFactory.class)
286 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, DeLorean.class));
287 }
288 });
289 ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
290
291 DeLorean deLorean = (DeLorean) carFactory.create(Color.GRAY);
292 assertEquals(Color.GRAY, deLorean.color);
293 assertEquals("Flux Capacitor", deLorean.features.iterator().next());
294 assertEquals(new Integer(88), deLorean.featureActivationSpeeds.iterator().next());
295 }
296
297 public static class DeLorean implements Car {
298 private final Set<String> features;
299 private final Set<Integer> featureActivationSpeeds;
300 private final Color color;
301
302 @AssistedInject
303 public DeLorean(
304 Set<String> extraFeatures, Set<Integer> featureActivationSpeeds, @Assisted Color color) {
305 this.features = extraFeatures;
306 this.featureActivationSpeeds = featureActivationSpeeds;
307 this.color = color;
308 }
309 }
310
311 public void testTypeTokenProviderInjection() {
312 Injector injector = Guice.createInjector(new AbstractModule() {
313 @Override
314 protected void configure() {
315 bind(new TypeLiteral<Set<String>>() { }).toInstance(Collections.singleton("Datsun"));
316 bind(ColoredCarFactory.class)
317 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Z.class));
318 }
319 });
320 ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
321
322 Z orangeZ = (Z) carFactory.create(Color.ORANGE);
323 assertEquals(Color.ORANGE, orangeZ.color);
324 assertEquals("Datsun", orangeZ.manufacturersProvider.get().iterator().next());
325 }
326
327 public static class Z implements Car {
328 private final Provider<Set<String>> manufacturersProvider;
329 private final Color color;
330
331 @AssistedInject
332 public Z(Provider<Set<String>> manufacturersProvider, @Assisted Color color) {
333 this.manufacturersProvider = manufacturersProvider;
334 this.color = color;
335 }
336 }
337
338 public static class Prius implements Car {
339 @SuppressWarnings("unused")
340 private final Color color;
341
342 @AssistedInject
343 private Prius(@Assisted Color color) {
344 this.color = color;
345 }
346 }
347
348 public void testAssistInjectionInNonPublicConstructor() {
349 Injector injector = Guice.createInjector(new AbstractModule() {
350 @Override
351 protected void configure() {
352 bind(ColoredCarFactory.class)
353 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Prius.class));
354 }
355 });
356 Car car = injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE);
357 }
358
359 public static class ExplodingCar implements Car {
360 @AssistedInject
361 public ExplodingCar(@Assisted Color color) {
362 throw new IllegalStateException("kaboom!");
363 }
364 }
365
366 public void testExceptionDuringConstruction() {
367 Injector injector = Guice.createInjector(new AbstractModule() {
368 @Override
369 protected void configure() {
370 bind(ColoredCarFactory.class).toProvider(
371 FactoryProvider.newFactory(ColoredCarFactory.class, ExplodingCar.class));
372 }
373 });
374 try {
375 injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE);
376 fail();
377 } catch (IllegalStateException e) {
378 assertEquals("kaboom!", e.getMessage());
379 }
380 }
381
382 public static class DefectiveCar implements Car {
383 @AssistedInject
384 public DefectiveCar() throws ExplosionException, FireException {
385 throw new ExplosionException();
386 }
387 }
388
389 public static class ExplosionException extends Exception { }
390 public static class FireException extends Exception { }
391
392 public interface DefectiveCarFactoryWithNoExceptions {
393 Car createCar();
394 }
395
396 public interface DefectiveCarFactory {
397 Car createCar() throws FireException;
398 }
399
400 public void testFactoryMethodMustDeclareAllConstructorExceptions() {
401 try {
402 FactoryProvider.newFactory(DefectiveCarFactoryWithNoExceptions.class, DefectiveCar.class);
403 fail();
limpbizkitfcbdf992008-11-26 02:37:35 +0000404 } catch (ConfigurationException expected) {
limpbizkiteab76472008-05-26 19:45:12 +0000405 assertContains(expected.getMessage(), "no compatible exception is thrown");
limpbizkite451ef72007-12-19 01:15:59 +0000406 }
407 }
408
409 public interface CorrectDefectiveCarFactory {
410 Car createCar() throws FireException, ExplosionException;
411 }
412
413 public void testConstructorExceptionsAreThrownByFactory() {
414 Injector injector = Guice.createInjector(new AbstractModule() {
415 @Override
416 protected void configure() {
417 bind(CorrectDefectiveCarFactory.class).toProvider(
418 FactoryProvider.newFactory(
419 CorrectDefectiveCarFactory.class, DefectiveCar.class));
420 }
421 });
422 try {
423 injector.getInstance(CorrectDefectiveCarFactory.class).createCar();
424 fail();
425 } catch (FireException e) {
426 fail();
427 } catch (ExplosionException expected) {
428 }
429 }
430
431 public static class MultipleConstructorDefectiveCar implements Car {
432 @AssistedInject
433 public MultipleConstructorDefectiveCar() throws ExplosionException {
434 throw new ExplosionException();
435 }
436
437 @AssistedInject
438 public MultipleConstructorDefectiveCar(@Assisted Color c) throws FireException {
439 throw new FireException();
440 }
441 }
442
443 public interface MultipleConstructorDefectiveCarFactory {
444 Car createCar() throws ExplosionException;
445 Car createCar(Color r) throws FireException;
446 }
447
448 public void testMultipleConstructorExceptionMatching() {
449 Injector injector = Guice.createInjector(new AbstractModule() {
450 @Override
451 protected void configure() {
452 bind(MultipleConstructorDefectiveCarFactory.class).toProvider(
453 FactoryProvider.newFactory(
454 MultipleConstructorDefectiveCarFactory.class,
455 MultipleConstructorDefectiveCar.class));
456 }
457 });
458 MultipleConstructorDefectiveCarFactory factory
459 = injector.getInstance(MultipleConstructorDefectiveCarFactory.class);
460 try {
461 factory.createCar();
462 fail();
463 } catch (ExplosionException expected) {
464 }
465
466 try {
467 factory.createCar(Color.RED);
468 fail();
469 } catch (FireException expected) {
470 }
471 }
472
473 public static class WildcardCollection {
474
475 public interface Factory {
476 WildcardCollection create(Collection<?> items);
477 }
478
479 @AssistedInject
480 public WildcardCollection(@Assisted Collection<?> items) { }
481 }
482
483 public void testWildcardGenerics() {
484 Injector injector = Guice.createInjector(new AbstractModule() {
485 @Override
486 protected void configure() {
487 bind(WildcardCollection.Factory.class).toProvider(
488 FactoryProvider.newFactory(
489 WildcardCollection.Factory.class,
490 WildcardCollection.class));
491 }
492 });
493 WildcardCollection.Factory factory = injector.getInstance(WildcardCollection.Factory.class);
494 factory.create(Collections.emptyList());
495 }
496
limpbizkit5741fb82008-02-18 21:04:53 +0000497 public static class SteeringWheel {}
498
499 public static class Fiat implements Car {
500 @SuppressWarnings("unused")
501 private final SteeringWheel steeringWheel;
502 @SuppressWarnings("unused")
503 private final Color color;
504
505 @AssistedInject
506 public Fiat(SteeringWheel steeringWheel, @Assisted Color color) {
507 this.steeringWheel = steeringWheel;
508 this.color = color;
509 }
510 }
511
512 public void testFactoryWithImplicitBindings() {
513 Injector injector = Guice.createInjector(new AbstractModule() {
514 @Override
515 protected void configure() {
516 bind(ColoredCarFactory.class).toProvider(
517 FactoryProvider.newFactory(
518 ColoredCarFactory.class,
519 Fiat.class));
520 }
521 });
limpbizkit6c0feb52008-02-18 21:11:00 +0000522
limpbizkit5741fb82008-02-18 21:04:53 +0000523 ColoredCarFactory coloredCarFactory = injector.getInstance(ColoredCarFactory.class);
524 Fiat fiat = (Fiat) coloredCarFactory.create(Color.GREEN);
525 assertEquals(Color.GREEN, fiat.color);
526 assertNotNull(fiat.steeringWheel);
527 }
528
529 public void testFactoryFailsWithMissingBinding() {
530 try {
531 Guice.createInjector(new AbstractModule() {
532 @Override protected void configure() {
533 bind(ColoredCarFactory.class)
534 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
535 }
536 });
limpbizkiteab76472008-05-26 19:45:12 +0000537 fail();
limpbizkit9532e622008-06-18 08:20:54 +0000538 } catch (CreationException expected) {
539 assertContains(expected.getMessage(),
limpbizkit72d11dd2008-11-02 07:59:13 +0000540 "1) Parameter of type 'double' is not injectable or annotated with @Assisted");
limpbizkit5741fb82008-02-18 21:04:53 +0000541 }
542 }
limpbizkitcb93c792008-09-29 18:24:45 +0000543
544 public void testMethodsDeclaredInObject() {
545 Injector injector = Guice.createInjector(new AbstractModule() {
546 @Override protected void configure() {
547 bind(Double.class).toInstance(5.0d);
548 bind(ColoredCarFactory.class)
549 .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
550 }
551 });
552
553 ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
554
555 carFactory.equals(carFactory);
556 carFactory.hashCode();
557 carFactory.toString();
558 }
limpbizkite451ef72007-12-19 01:15:59 +0000559
limpbizkit2d633cd2008-12-09 06:26:00 +0000560 public void testAssistedInjectConstructorAndAssistedFactoryParameterMustNotMix() {
561 try {
562 Guice.createInjector(new AbstractModule() {
563 @Override protected void configure() {
564 bind(Double.class).toInstance(5.0d);
565 bind(AssistedParamsFactory.class)
566 .toProvider(FactoryProvider.newFactory(AssistedParamsFactory.class, Mustang.class));
567 }
568 });
569 fail();
570 } catch (CreationException expected) {
571 assertContains(expected.getMessage(), "Factory method "
572 + AssistedParamsFactory.class.getName() + ".create() has an @Assisted parameter, which "
573 + "is incompatible with the deprecated @AssistedInject annotation.");
574 }
575 }
576
577 interface AssistedParamsFactory {
578 Car create(@Assisted Color color);
579 }
limpbizkit9d6b6562009-02-27 21:59:15 +0000580
581 interface GenericColoredCarFactory<T extends Car> {
582 T create(Color color);
583 }
584
585 public void testGenericAssistedFactory() {
586 final TypeLiteral<GenericColoredCarFactory<Mustang>> mustangTypeLiteral
587 = new TypeLiteral<GenericColoredCarFactory<Mustang>>() {};
588 final TypeLiteral<GenericColoredCarFactory<Camaro>> camaroTypeLiteral
589 = new TypeLiteral<GenericColoredCarFactory<Camaro>>() {};
590
591 Injector injector = Guice.createInjector(new AbstractModule() {
592 @Override
593 protected void configure() {
594 bind(Double.class).toInstance(5.0d);
595 bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
596 bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
597 bind(mustangTypeLiteral).toProvider(
598 FactoryProvider.newFactory(mustangTypeLiteral, TypeLiteral.get(Mustang.class)));
599 bind(camaroTypeLiteral).toProvider(
600 FactoryProvider.newFactory(camaroTypeLiteral, TypeLiteral.get(Camaro.class)));
601 }
602 });
603
604 GenericColoredCarFactory<Mustang> mustangFactory
605 = injector.getInstance(Key.get(mustangTypeLiteral));
606 GenericColoredCarFactory<Camaro> camaroFactory
607 = injector.getInstance(Key.get(camaroTypeLiteral));
608
609 Mustang blueMustang = mustangFactory.create(Color.BLUE);
610 assertEquals(Color.BLUE, blueMustang.color);
611 assertEquals(5.0d, blueMustang.engineSize);
612
613 Camaro redCamaro = camaroFactory.create(Color.RED);
614 assertEquals(Color.RED, redCamaro.color);
615 assertEquals(1984, redCamaro.modelYear);
616 assertEquals(250, redCamaro.horsePower);
617 }
618
619 public interface Insurance<T extends Car> {
620 }
621
622 public static class MustangInsurance implements Insurance<Mustang> {
623 private final double premium;
624 private final double limit;
625 private Mustang car;
626
627 @AssistedInject
628 public MustangInsurance(@Named("lowLimit") double limit, @Assisted Mustang car,
629 @Assisted double premium) {
630 this.premium = premium;
631 this.limit = limit;
632 this.car = car;
633 }
634
635 public void sell() {}
636 }
637
638 public static class CamaroInsurance implements Insurance<Camaro> {
639 private final double premium;
640 private final double limit;
641 private Camaro car;
642
643 @AssistedInject
644 public CamaroInsurance(@Named("highLimit") double limit, @Assisted Camaro car,
645 @Assisted double premium) {
646 this.premium = premium;
647 this.limit = limit;
648 this.car = car;
649 }
650
651 public void sell() {}
652 }
653
654 public interface MustangInsuranceFactory {
655 public Insurance<Mustang> create(Mustang car, double premium);
656 }
657
658 public interface CamaroInsuranceFactory {
659 public Insurance<Camaro> create(Camaro car, double premium);
660 }
661
662 public void testAssistedFactoryForConcreteType() {
663
664 Injector injector = Guice.createInjector(new AbstractModule() {
665 @Override
666 protected void configure() {
667 bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
668 bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
669 bind(MustangInsuranceFactory.class).toProvider(
670 FactoryProvider.newFactory(MustangInsuranceFactory.class, MustangInsurance.class));
671 bind(CamaroInsuranceFactory.class).toProvider(
672 FactoryProvider.newFactory(CamaroInsuranceFactory.class, CamaroInsurance.class));
673 }
674 });
675
676 MustangInsuranceFactory mustangInsuranceFactory =
677 injector.getInstance(MustangInsuranceFactory.class);
678 CamaroInsuranceFactory camaroInsuranceFactory =
679 injector.getInstance(CamaroInsuranceFactory.class);
680
681 Mustang mustang = new Mustang(5000d, Color.BLACK);
682 MustangInsurance mustangPolicy =
683 (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
684 assertEquals(800.0d, mustangPolicy.premium);
685 assertEquals(50000.0d, mustangPolicy.limit);
686
687 Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
688 CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d);
689 assertEquals(800.0d, camaroPolicy.premium);
690 assertEquals(100000.0d, camaroPolicy.limit);
691 }
692
693 public interface InsuranceFactory<T extends Car> {
694 public Insurance<T> create(T car, double premium);
695 }
696
697 public void testAssistedFactoryForParameterizedType() {
698 final TypeLiteral<InsuranceFactory<Mustang>> mustangInsuranceFactoryType =
699 new TypeLiteral<InsuranceFactory<Mustang>>() {};
700 final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType =
701 new TypeLiteral<InsuranceFactory<Camaro>>() {};
702
703 Injector injector = Guice.createInjector(new AbstractModule() {
704 @Override
705 protected void configure() {
706 bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
707 bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
708 bind(mustangInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
709 mustangInsuranceFactoryType, TypeLiteral.get(MustangInsurance.class)));
710 bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
711 camaroInsuranceFactoryType, TypeLiteral.get(CamaroInsurance.class)));
712 }
713 });
714
715 InsuranceFactory<Mustang> mustangInsuranceFactory =
716 injector.getInstance(Key.get(mustangInsuranceFactoryType));
717 InsuranceFactory<Camaro> camaroInsuranceFactory =
718 injector.getInstance(Key.get(camaroInsuranceFactoryType));
719
720 Mustang mustang = new Mustang(5000d, Color.BLACK);
721 MustangInsurance mustangPolicy =
722 (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
723 assertEquals(800.0d, mustangPolicy.premium);
724 assertEquals(50000.0d, mustangPolicy.limit);
725
726 Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
727 CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d);
728 assertEquals(800.0d, camaroPolicy.premium);
729 assertEquals(100000.0d, camaroPolicy.limit);
730 }
731
732 public static class AutoInsurance<T extends Car> implements Insurance<T> {
733 private final double premium;
734 private final double limit;
735 private final T car;
736
737 @AssistedInject
738 public AutoInsurance(double limit, @Assisted T car, @Assisted double premium) {
739 this.limit = limit;
740 this.car = car;
741 this.premium = premium;
742 }
743
744 public void sell() {}
745 }
746
747 public void testAssistedFactoryForTypeVariableParameters() {
748 final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType =
749 new TypeLiteral<InsuranceFactory<Camaro>>() {};
750
751 Injector injector = Guice.createInjector(new AbstractModule() {
752 @Override
753 protected void configure() {
754 bind(Double.class).toInstance(50000.0d);
755 bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
756 camaroInsuranceFactoryType, new TypeLiteral<AutoInsurance<Camaro>>() {}));
757 }
758 });
759
760 InsuranceFactory<Camaro> camaroInsuranceFactory =
761 injector.getInstance(Key.get(camaroInsuranceFactoryType));
762
763 Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
764 AutoInsurance camaroPolicy = (AutoInsurance) camaroInsuranceFactory.create(camaro, 800.0d);
765 assertEquals(800.0d, camaroPolicy.premium);
766 assertEquals(50000.0d, camaroPolicy.limit);
767 assertEquals(camaro, camaroPolicy.car);
768 }
limpbizkite451ef72007-12-19 01:15:59 +0000769}