For Contact Personal Assistant I am using GUICE. After being introduced to Dependency Injection, or Inversion of Control, I appreciate its awesomeness, if I don’t fully understand it. One of my main issues with fully adopting this paradigm shift, has been the usual barrage of questions a developer asks and answers in their own head in a daily basis, and the main one for me so far was.
How do I implement a conditional logic for an implementation instance based on runtime parameters?
Sounds a little abstract, I know. So lets try an example. Imagine you have a control which renders some information from a IDataServer interface but at runtime you have several Implementations of the IDataServer interface to chose from.
I have thought of many ways this could be achieved, but have known, them all to be hacky, my implementation based on how I currently understand GUICE, and trying to fit it into what I require. As they say with great power comes great responsibility, and I want to use this framework correctly, not in hacked way that I can get it to work given my current level of knowledge.
It turns out the solution is as simple as it is beautiful:
USE MAP BINDER!
Luckily the answer is discussed on this thread which I replicate here:
1: public class CalculatorModule extends AbstractModule {
2: protected void configure() {
3: MapBinder<Types, Class<ICalculator>> mapbinder
4: = MapBinder.newMapBinder(binder(), Types.class,
5: ICalculator.class);
6: mapbinder.addBinding(Types.A).toInstance(ACalculator.class);
7: mapbinder.addBinding(Types.B).toInstance(BCalculator.class);
8: mapbinder.addBinding(Types.C).toInstance(CCalculator.class);
9: }
10: }
11: @Singleton
12: public class CalculatorFactory {
13: private final Injector injector;
14: private final Map<Types, Class<Calculator>> calculators;
15: @Inject
16: public CalculatorFactory(Injector injector, Map<Types,
17: Class<Calculator>> calculators) {
18: this.injector = injector;
19: this.calculators = calculators;
20: }
21: public ICalculator create(UserGroup group) {
22: injector.getInstance(calculators.get(group.getType));
23: }
24: }
This example uses a calculator factory to allow the user to select whether they want implementation A, B or C. Simply inject the calculator factory into whichever class requires it.
Beautiful!
No comments:
Post a Comment