Guice2.0
‐New Features and 3rd Party Modules‐


                     Jul 15th, 2009
introduction
Name
   Masaaki Yonebayashi
ID
  id:yone098
Blog
  http://d.hatena.ne.jp/yone098/
Company
  Abby Co.,Ltd.  President
Agenda
Guice2.0 New Features
 Provider Methods
 Binding Override
 MultiBindings, MapBindings
 Private Modules

Tips
Third Party Modules
 Testing
 Other Language
Guice2.0




New Features
Guice2.0
Guice 2.0
 Released May 19, 2009
URL
 http://code.google.com/p/google‐guice/
guice‐2.0‐no_aop.jar
 For Android(not support AOP)
Wiki
 http://code.google.com/p/google‐guice/wiki/Guice20
New Features




Provider Methods
Provider Methods
     example          public interface Pet {
                        void run();
                      }

public class Cat implements Pet {    public class Dog implements Pet {
  private String name;                 private String name;
  public Cat(String name) {            public Dog(String name) {
    this.name = name;                    this.name = name;
  }                                    }
  public void run() {                  public void run() {
   System.out.println(                  System.out.println(
     name + “ Cat is run");               name + “ Dog is run");
 }                                     }
}                                    }
Provider Methods
    Guice1.0
Injector injector = Guice.createInjector(new AbstractModule() {
  @Override
  public void configure() {
    bind(Pet.class).toProvider(new Provider<Pet>() {
      public Pet get() {
        return new Dog("new Provider<Pet>");
      }
    }).in(Singleton.class);
  }
});
Pet pet = injector.getInstance(Pet.class);
pet.run();
Provider Methods
    Guice1.0
Injector injector = Guice.createInjector(new AbstractModule() {
  @Override
  public void configure() {
    bind(Pet.class).toProvider(new Provider<Pet>() {
      public Pet get() {
   new Provider<Pet> Dog is run
        return new Dog("new Provider<Pet>");
      }
    }).in(Singleton.class);
  }
});
Pet pet = injector.getInstance(Pet.class);
pet.run();
Provider Methods
    Guice2.0
Injector injector = Guice.createInjector(new AbstractModule() {
  @Override
  public void configure() {
  }
  @Provides @Singleton
  Pet providePet() {
    return new Cat("@Provides");
  }
});
Pet pet = injector.getInstance(Pet.class);
pet.run();
Provider Methods
    Guice2.0
Injector injector = Guice.createInjector(new AbstractModule() {
  @Override
  public void configure() {
  }
  @Provides @Singleton
   @Provides Cat is run
  Pet providePet() {
    return new Cat("@Provides");
  }
});
Pet pet = injector.getInstance(Pet.class);
pet.run();
Question
    Guice2.0
Injector injector = Guice.createInjector(new AbstractModule() {
  @Override
  public void configure() {
  }
  @Provides @Singleton
  Pet providePet() {
    return new Cat("@Provides");
  }
  @Provides @Singleton
  Pet providePet2() {
    return new Cat("@Provides2");
  }
});
Provider Methods
   CreationException :(
Exception in thread "main" 
  com.google.inject.CreationException: Guice creation 
  errors:

1) A binding to samples.providermethod.Pet was already 
  configured at 
  samples.providermethod.ProviderMethods$1.providePet().
  at 
  samples.providermethod.ProviderMethods$1.providePet2(P
  roviderMethods.java:33)
Provider Methods
   CreationException :(
Exception in thread "main" 
  com.google.inject.CreationException: Guice creation 
  errors:

1) A binding to samples.providermethod.Pet was already 
  configured at 
  samples.providermethod.ProviderMethods$1.providePet().
  at 
  samples.providermethod.ProviderMethods$1.providePet2(P
  roviderMethods.java:33)


                                          demo
Provider Methods




solves it
solved it
    Provides with Named
Injector injector = Guice.createInjector(new AbstractModule() {
  @Override
  public void configure() {
  }
  @Provides @Singleton
  Pet providePet() {
    return new Cat("@Provides");
  }
  @Provides @Singleton @Named(“NYAAA”)
  Pet providePet2() {
    return new Cat("@Provides2");
  }
});
solved it
   named
import static
  com.google.inject.name.Names.named;
Pet pet = injector.getInstance(Pet.class);
pet.run();

Pet nyaaa = injector.getInstance(
    Key.get(Pet.class, named("NYAAA")));
nyaaa.run();
solved it
   named
import static
  com.google.inject.name.Names.named;
Pet pet = injector.getInstance(Pet.class);
pet.run();
  @Provides Cat is run
  @Provedes2 Cat is run
Pet nyaaa = injector.getInstance(
    Key.get(Pet.class, named("NYAAA")));
nyaaa.run();
Question
   void Provider Methods
Injector injector = Guice.createInjector(new
  AbstractModule() {
  @Override
  public void configure() {
  }
  @Provides
  void sample() {
  }
});
Provider Methods
   CreationException :(
Exception in thread "main" 
  com.google.inject.CreationException: Guice 
  creation errors:

1) Provider methods must return a value. Do not 
  return void.
  at 
  samples.providermethod.ProviderMethods$1.sample(P
  roviderMethods.java:40)
Provider Methods
   CreationException :(
Exception in thread "main" 
  com.google.inject.CreationException: Guice 
  creation errors:

1) Provider methods must return a value. Do not 
  return void.
  at 
  samples.providermethod.ProviderMethods$1.sample(P
  roviderMethods.java:40)


                                       demo
New Features



Provider Methods Summary
Provider Methods summary


The definition is simple.
There is no generation cost of the 
Provider class.
It is a short cut.
New Features




Binding Overrides
Binding Overrides
   Sample Module
private static Module module1() {
  return new AbstractModule() {
     protected void configure() {
       bind(Pet.class).to(Dog.class);
    }
  };
}
Binding Overrides
   Module override
Injector injector = createInjector(
  Modules.override(module1())
    .with(new AbstractModule() {
      protected void configure() {
        bind(Pet.class).to(Cat.class);
      }
    }
));
Pet pet = injector.getInstance(Pet.class);
pet.run();
Binding Overrides
   Module override
Injector injector = createInjector(
  Modules.override(module1())
    .with(new AbstractModule() {
      protected void configure() {
   Cat is run
        bind(Pet.class).to(Cat.class);
      }
    }
));
Pet pet = injector.getInstance(Pet.class);
pet.run();
New Features



Binding Overrides
Override multiple
Binding Overrides
    override multiple
private static <T> Module newModule(final T bound) {
  return new AbstractModule() {
     protected void configure() {
       @SuppressWarnings("unchecked")
       Class<T> type = (Class<T>) bound.getClass();
       bind(type).toInstance(bound);
     }
  };
}
Binding Overrides
  override multiple
Module module = Modules.override(
   newModule("A"), 
   newModule(1),
   newModule(0.5f)
).with(
   newModule("B"), 
   newModule(2),
   newModule(1.5d)
);
Injector injector = createInjector(module);
Binding Overrides
 override multiple
assertEquals("B", 
    injector.getInstance(String.class));
assertEquals(0.5f, 
    injector.getInstance(Float.class));
assertEquals(1.5d, 
    injector.getInstance(Double.class));
New Features



Binding Overrides
Override constant
Binding Overrides
  override constant
Module original = new AbstractModule() {
  protected void configure() {
     bindConstant().annotatedWith(named(“c9")).to(“ak");
  }
};
Module replacements = new AbstractModule() {
   protected void configure() {
     bindConstant().annotatedWith(named(“c9")).to(“yaman");
   }
};
Injector injector = 
   createInjector(Modules.override(original)
                  .with(replacements));
Binding Overrides
 override constant
Injector injector = 
 createInjector(Modules.override(original)
      .with(replacements));

assertEquals("yaman",
  injector.getInstance(
    Key.get(String.class, named("c9"))));
Binding Override summary


An existing module can be recycled.
The offered module can be 
customized.
New Features



 MultiBindings,
MapBindings
Guice2.0

dependency
 guice‐multibindings‐2.0.jar
 artifactId
  multibindings
 groupId
  com.google.inject.extension
New Features




MultiBindings
MultiBindings
  MultiBindings
Module abc = new AbstractModule() {
   protected void configure() {
     Multibinder<String> multibinder =
       Multibinder.newSetBinder(
           binder(), String.class);
     multibinder.addBinding().toInstance("A");
     multibinder.addBinding().toInstance("B");
     multibinder.addBinding().toInstance("C");
   }
};
MultiBindings
  MultiBindings
Injector injector = Guice.createInjector(abc);
Set<String> abcStr = 
  injector.getInstance(Key.get(
    new TypeLiteral<Set<String>>() {}
  ));

assertEquals(setOf("A", "B", "C"), abcStr);
MultiBindings
  MultiBindings
private static class Test {
  @Inject
  private Set<String> multiString;
}

Test test = injector.getInstance(Test.class);
assertEquals(setOf("A", "B", "C"), 
  test.multiString);
New Features




MapBindings
MapBindings
  MapBindings
Module abc = new AbstractModule() {
   protected void configure() {
     MapBinder<String, String> multibinder =     
     MapBinder.newMapBinder(
       binder(), String.class, String.class);
     multibinder.addBinding("a").toInstance("A");
     multibinder.addBinding("b").toInstance("B");
     multibinder.addBinding("c").toInstance("C");
   }
};
MapBindings
  MapBindings
Injector injector = Guice.createInjector(abc);
Map<String, String> abcMap = 
  injector.getInstance(Key.get(
    new TypeLiteral<Map<String, String>>(){}
  ));

assertEquals(
   mapOf("a", "A", "b", "B", "c", "C"),
   abcMap
);
MapBindings
  MapBindings
private static class Test {
  @Inject
  private Map<String, String> map;
}

Test test = injector.getInstance(Test.class);
assertEquals(
   mapOf("a", "A", "b", "B", "c", "C"), 
   test.map
);
New Features



MapBindings
•with AnnotationType
MapBindings
 MapBindings with AnnotationType
/**
 * Ikemen annotation
 */
@Retention(RUNTIME)
@BindingAnnotation
@interface C9 {
}
MapBindings
  MapBindings with AnnotationType
Injector injector = Guice.createInjector(
  new AbstractModule() {
  protected void configure() {
    MapBinder<String, Integer> mapBinder = MapBinder
    .newMapBinder(binder(), 
        String.class, Integer.class, C9.class);
    mapBinder.addBinding("yaman").toInstance(35);
    mapBinder.addBinding("shot6").toInstance(31);
    mapBinder.addBinding("yone098").toInstance(31);
    mapBinder.addBinding("skirnir").toInstance(52);
  }
});
MapBindings
  MapBindings with AnnotationType
Map<String, Integer> abc = 
  injector.getInstance(Key.get(
    new TypeLiteral<Map<String, Integer>>(){},
    C9.class));

assertEquals(
  mapOf("yaman", 35, "shot6", 31, 
    "yone098", 31, "skirnir", 52), 
  abc
);
MapBindings
  MapBindings with AnnotationType
private static class Ikemen {
  @Inject
  @C9
  Map<String, Integer> map;
}

Ikemen ikemen = injector.getInstance(Ikemen.class);
assertEquals(
  mapOf("yaman", 35, "shot6", 31, 
        "yone098", 31, "skirnir", 52), 
  ikemen.map);
MultiBindings summary


The advantage of MultiBindings is 
not found. :(
It depends on guice‐multibindings‐
2.0.jar.
New Features




PrivateModule
PrivateModule
  PrivateModule
Injector injector = Guice.createInjector(
  new PrivateModule() {
  public void configure() {
    bind(String.class).annotatedWith(named("c9"))
     .toInstance("katayama");
     expose(String.class).annotatedWith(named("c9"));
  }
});
assertEquals("katayama",
  injector.getInstance(Key.get(String.class,
    named("c9"))));
PrivateModule
  PrivateModule
private static class Test {
@Inject
@Named("c9")
private String c9katayama;
}

Test test = injector.getInstance(Test.class);
assertEquals("katayama", test.c9katayama);
New Features



PrivateModule
expose
PrivateModule
  PrivateModule
Injector injector = Guice.createInjector(
  new PrivateModule() {
  public void configure() {
    bind(String.class).annotatedWith(named("c9"))
     .toInstance("katayama");
     expose(String.class).annotatedWith(named("c9"));
  }
});
assertEquals("katayama",
  injector.getInstance(Key.get(String.class,
    named("c9"))));
PrivateModule
  PrivateModule
Injector injector = Guice.createInjector(
  new PrivateModule() {
  public void configure() {
    bind(String.class).annotatedWith(named("c9"))
     .toInstance("katayama");
     expose(String.class).annotatedWith(named("c9"));
  }
});
assertEquals("katayama",
  injector.getInstance(Key.get(String.class,
    named("c9"))));

                                         demo
New Features



PrivateModule
@Exposed
PrivateModule
    PrivateModule
Injector injector = Guice.createInjector(
  new PrivateModule(){
    protected void configure() { }
    @Provides @Named("c9") @Exposed 
    String provideKata() { return "KATA"; }
  }, new AbstractModule() {
    protected void configure() { }
    @Provides @Named("yaman")
    String provideYama(@Named("c9") String c9) {
      return c9 + "YAMA";
    }
});
PrivateModule
  PrivateModule
assertEquals("KATAYAMA", 
  injector.getInstance(Key.get(
    String.class,
    named("yaman")))
);




                                  demo
PrivateModule


Use it positively if you make the 
framework.
It will become easy to design the 
module.
The module can be safely used by 
limiting scope.
Guice2.0
New Features




InjectionListener



                demo
New Features




Names.bindProperties




                 demo
Guice2.0



Third Party Modules
Third Party Modules




Testing
Third Party Modules
GuiceBerry
 JUnit and integration testing
 http://code.google.com/p/guiceberry/
AtUnit
 JUnit and mocking frameworks (JMock, 
 EasyMock)
 http://code.google.com/p/atunit/
Third Party Modules




Other Language
Third Party Modules
Groovy‐Guice(Groovy)
 http://code.google.com/p/groovy‐guice/
Ninject(.NET)
 http://ninject.org/
Snake Guice(Python)
 http://code.google.com/p/snake‐guice/
Smartypants‐IOC(Flex)
 http://code.google.com/p/smartypants‐
 ioc/
Guice2.0




Summary
summary



Enjoy! Guice2.0
Haiku


Today
very hot
No Haiku❤
Thank you!
    :)

Guice2.0