KEMBAR78
Guice tutorial | PDF
GIN
A basic tutorial
       by

 anhquan.de
What the heck is Google GIN?

• GIN = GWT INjection
• Guice brings automatic dependency injection to server side
  code, while GIN is for client-side code.
• GIN is built on top of Guice and uses (a subset of) Guice's
  binding language
What the heck is Google GIN?

• GIN = GWT INjection
• Guice brings automatic dependency injection to server side
  code, while GIN is for client-side code.
• GIN is built on top of Guice and uses (a subset of) Guice's
  binding language

             GWT client-side
                 code




                  GIN
What the heck is Google GIN?

• GIN = GWT INjection
• Guice brings automatic dependency injection to server side
  code, while GIN is for client-side code.
• GIN is built on top of Guice and uses (a subset of) Guice's
  binding language

             GWT client-side           GWT server-side
                 code                      code




                  GIN                      Guice
This tutorial shows you


How to use GIN ?
5 Steps to remember
1. Design the application with Interfaces IA,IB,…
5 Steps to remember
1. Design the application with Interfaces IA,IB,…
2. Create concrete classes AImpl, BImpl,… to implement interfaces IA,IB,…
   Remember: use @Inject to mark the non-default constructor.
5 Steps to remember
1. Design the application with Interfaces IA,IB,…
2. Create concrete classes AImpl, BImpl,… to implement interfaces IA,IB,…
   Remember: use @Inject to mark the non-default constructor.
3. Create AppClientModule to configure which implementation is bound to which interface
5 Steps to remember
1. Design the application with Interfaces IA,IB,…
2. Create concrete classes AImpl, BImpl,… to implement interfaces IA,IB,…
   Remember: use @Inject to mark the non-default constructor.
3. Create AppClientModule to configure which implementation is bound to which interface
4. Create interface AppGinjector with the AppClientModule in the annotation @GinModules.

     @GinModules({AppClientModule.class, other modules …})
5 Steps to remember
1. Design the application with Interfaces IA,IB,…
2. Create concrete classes AImpl, BImpl,… to implement interfaces IA,IB,…
   Remember: use @Inject to mark the non-default constructor.
3. Create AppClientModule to configure which implementation is bound to which interface
4. Create interface AppGinjector with the AppClientModule in the annotation @GinModules.

     @GinModules({AppClientModule.class, other modules …})



5. Generate code for AppGinjector and use it


      private final AppGinjector injector = GWT.create(AppGinjector.class);

      AppPresenter aPres = injector.getAppPresenter();
      aPres.bind();

      RootPanel.get().add(aPres.getDisplay().asWidget());
Step 1: Design an Interface

public class ConfigPresenter extends WidgetPresenter<ConfigPresenter.Display>{

    public interface Display extends NameAwareWidgetDisplay, WidgetDisplay {
      public HasClickHandlers getSaveClick();
      public void updateConfig(Config config);
    }
…
}
Step 1: Design an Interface

public class ConfigPresenter extends WidgetPresenter<ConfigPresenter.Display>{

    public interface Display extends NameAwareWidgetDisplay, WidgetDisplay {
      public HasClickHandlers getSaveClick();
      public void updateConfig(Config config);
    }
…
}


                         For gwt-dispatch developers:
                         Normally, we create a Display interface as an inner interface of
                         a Presenter class
Step 2: Implement the interface


public class ConfigView extends Composite implements ConfigPresenter.Display {

    private VerticalPanel panel = new VerticalPanel();

    private AppConstants constants;

    @Inject
    public ConfigView(AppConstants constants, AppMessages messages) {
       this.constants = constants;
       panel.addStyleName(AppCSS.C_config_container);
       panel.add(new HTML("<h1>Config view: comming soon<h1>"));
       initWidget(panel);
    }
…
}
Step 2: Implement the interface
    If the class has no default constructor, then a @Inject annotation is required. Otherwise, you will get
    a RuntimeException (“No @Inject or default constructor found for class …. ”)




public class ConfigView extends Composite implements ConfigPresenter.Display {

      private VerticalPanel panel = new VerticalPanel();

      private AppConstants constants;

      @Inject
      public ConfigView(AppConstants constants, AppMessages messages) {
         this.constants = constants;
         panel.addStyleName(AppCSS.C_config_container);
         panel.add(new HTML("<h1>Config view: comming soon<h1>"));
         initWidget(panel);
      }
…
}
Step 3: Create class AppClientModule

public class AppClientModule extends AbstractPresenterModule {

@Override
protected void configure() {
bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class);
bind(PlaceManager.class).to(AppPlaceManager.class);
bindPresenter(LoginPresenter.class, LoginPresenter.Display.class, LoginView.class);
bindPresenter(MainPresenter.class, MainPresenter.Display.class, MainView.class);
bindPresenter(AppPresenter.class, AppPresenter.Display.class, AppView.class);
bind(LoginPresenterPlace.class).in(Singleton.class);
bind(ContactsPresenterPlace.class).in(Singleton.class);
…
bind(LoginPresenter.class).in(Singleton.class);
bind(LoginPresenter.Display.class).to(LoginView.class);



}
}
Step 3: Create class AppClientModule

public class AppClientModule extends AbstractPresenterModule {

@Override
protected void configure() {
bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class);
bind(PlaceManager.class).to(AppPlaceManager.class);
bindPresenter(LoginPresenter.class, LoginPresenter.Display.class, LoginView.class);
bindPresenter(MainPresenter.class, MainPresenter.Display.class, MainView.class);
bindPresenter(AppPresenter.class, AppPresenter.Display.class, AppView.class);
bind(LoginPresenterPlace.class).in(Singleton.class);
bind(ContactsPresenterPlace.class).in(Singleton.class);
…
bind(LoginPresenter.class).in(Singleton.class);
bind(LoginPresenter.Display.class).to(LoginView.class);



}
}                  Don’t need to bind LoginPresenter and LoginPresenter.Display
                   Because they are already “bind” above in the bindPresenter(…)


                         See the implementation of the bindPresenter() in the next slide …
Note: Implementation of bindPresenter()


public abstract class AbstractPresenterModule extends AbstractGinModule {

protected <D extends Display> void bindPresenter( Class<? extends Presenter> presenter,
Class<D> display, Class<? extends D> displayImpl )
{
        bind( presenter ).in( Singleton.class );
        bindDisplay( display, displayImpl );
}

protected <D extends Display> void bindDisplay( Class<D> display, Class<? extends D>
displayImpl )
{
        bind( display ).to( displayImpl );
}
…
}
Note: Implementation of bindPresenter()


public abstract class AbstractPresenterModule extends AbstractGinModule {

protected <D extends Display> void bindPresenter( Class<? extends Presenter> presenter,
Class<D> display, Class<? extends D> displayImpl )
{
        bind( presenter ).in( Singleton.class );
        bindDisplay( display, displayImpl );
}

protected <D extends Display> void bindDisplay( Class<D> display, Class<? extends D>
displayImpl )
{
        bind( display ).to( displayImpl );
}
…
}

      DisplayImpl class is bound to Display interface
Note: Implementation of bindPresenter()
             Presenter is bound as Singleton. It means there is no new instance
             created when you invoke AppGinjector.getPresenter()
public abstract class AbstractPresenterModule extends AbstractGinModule {

protected <D extends Display> void bindPresenter( Class<? extends Presenter> presenter,
Class<D> display, Class<? extends D> displayImpl )
{
        bind( presenter ).in( Singleton.class );
        bindDisplay( display, displayImpl );
}

protected <D extends Display> void bindDisplay( Class<D> display, Class<? extends D>
displayImpl )
{
        bind( display ).to( displayImpl );
}
…
}

      DisplayImpl class is bound to Display interface
Step 4: Define AppGinjector interface




@GinModules({ClientDispatchModule.class,AppClientModule.class})
public interface AppGinjector extends Ginjector {
    public AppPresenter getAppPresenter();
    public PlaceManager getPlaceManager();
    public EventBus      getEventBus();
}
Step 4: Define AppGinjector interface

 List of modules. Each module class contains only one
 configure() method to specify
 which implementation is bound to which interface.




@GinModules({ClientDispatchModule.class,AppClientModule.class})
public interface AppGinjector extends Ginjector {
    public AppPresenter getAppPresenter();
    public PlaceManager getPlaceManager();
    public EventBus      getEventBus();
}
Step 4: Define AppGinjector interface

 List of modules. Each module class contains only one
 configure() method to specify
 which implementation is bound to which interface.

                            A helper module provided by gwt-dispatch
                            (just ignore it for now)
@GinModules({ClientDispatchModule.class,AppClientModule.class})
public interface AppGinjector extends Ginjector {
    public AppPresenter getAppPresenter();
    public PlaceManager getPlaceManager();
    public EventBus      getEventBus();
}
Step 4: Define AppGinjector interface

 List of modules. Each module class contains only one
 configure() method to specify
 which implementation is bound to which interface.

                            A helper module provided by gwt-dispatch
                            (just ignore it for now)
@GinModules({ClientDispatchModule.class,AppClientModule.class})
public interface AppGinjector extends Ginjector {
    public AppPresenter getAppPresenter();
    public PlaceManager getPlaceManager();                        You create it
    public EventBus      getEventBus();
}
                                                                  in step 3!
Step 4: Define AppGinjector interface

 List of modules. Each module class contains only one
 configure() method to specify
 which implementation is bound to which interface.

                            A helper module provided by gwt-dispatch
                            (just ignore it for now)
@GinModules({ClientDispatchModule.class,AppClientModule.class})
public interface AppGinjector extends Ginjector {
    public AppPresenter getAppPresenter();
    public PlaceManager getPlaceManager();                        You create it
    public EventBus      getEventBus();
}
                                                                  in step 3!


                              Use whatever name you want!
Step 4: Define AppGinjector interface

 List of modules. Each module class contains only one
 configure() method to specify
 which implementation is bound to which interface.

                            A helper module provided by gwt-dispatch
                            (just ignore it for now)
@GinModules({ClientDispatchModule.class,AppClientModule.class})
public interface AppGinjector extends Ginjector {
    public AppPresenter getAppPresenter();
    public PlaceManager getPlaceManager();                        You create it
    public EventBus      getEventBus();
}
                                                                  in step 3!


                               Use whatever name you want!

         Return type is important. Injector will return the instance
         basing on type.
Step 5: Using Injector in the EntryPoint


public class App implements EntryPoint{

    private final AppGinjector injector = GWT.create(AppGinjector.class);

    public void onModuleLoad() {
          AppPresenter aPres = injector.getAppPresenter();

         aPres.bind();

         RootPanel.get().add(aPres.getDisplay().asWidget());

         PlaceManager placeManager = injector.getPlaceManager();

         placeManager.fireCurrentPlace();
    }

}
Step 5: Using Injector in the EntryPoint
                                                    GWT generates the implementation
                                                    of AppGinjector at compile time
public class App implements EntryPoint{

    private final AppGinjector injector = GWT.create(AppGinjector.class);

    public void onModuleLoad() {
          AppPresenter aPres = injector.getAppPresenter();

         aPres.bind();

         RootPanel.get().add(aPres.getDisplay().asWidget());

         PlaceManager placeManager = injector.getPlaceManager();

         placeManager.fireCurrentPlace();
    }

}
Step 5: Using Injector in the EntryPoint
                                                     GWT generates the implementation
                                                     of AppGinjector at compile time
 public class App implements EntryPoint{

     private final AppGinjector injector = GWT.create(AppGinjector.class);

     public void onModuleLoad() {
           AppPresenter aPres = injector.getAppPresenter();

           aPres.bind();

           RootPanel.get().add(aPres.getDisplay().asWidget());

           PlaceManager placeManager = injector.getPlaceManager();

           placeManager.fireCurrentPlace();
     }

 }



Here are all Interfaces. Their implementations are injected by GIN.
But which implementation is bound to which Interface? => See AppClientModule   .configure()
That’s it!
Learn more
Articles:
•   Google's MVP tutorial
•   Best Practices For Architecting Your GWT App session


Projects:
•   Project google-gin
•   Project google-guice
•   Project gwt-dispatch
•   Project gwt-presenter
•   Project gwt-platform
•   A project implement MVP patterns based on gwt-dispatch, gin, guice
•   Apache Hupa – a GWT based webmail (using maven+junit+eclipse, gwt-dispatch, gwt-
    presenter, gin, guin). Highly recommended!
•   TeampScape – Another tutorial projects about gwt+gae, gwt-dispatch, gwt-presenter,
    datastore/jdo
Thank you!
anhquan.de

Guice tutorial

  • 1.
    GIN A basic tutorial by anhquan.de
  • 2.
    What the heckis Google GIN? • GIN = GWT INjection • Guice brings automatic dependency injection to server side code, while GIN is for client-side code. • GIN is built on top of Guice and uses (a subset of) Guice's binding language
  • 3.
    What the heckis Google GIN? • GIN = GWT INjection • Guice brings automatic dependency injection to server side code, while GIN is for client-side code. • GIN is built on top of Guice and uses (a subset of) Guice's binding language GWT client-side code GIN
  • 4.
    What the heckis Google GIN? • GIN = GWT INjection • Guice brings automatic dependency injection to server side code, while GIN is for client-side code. • GIN is built on top of Guice and uses (a subset of) Guice's binding language GWT client-side GWT server-side code code GIN Guice
  • 5.
    This tutorial showsyou How to use GIN ?
  • 6.
    5 Steps toremember 1. Design the application with Interfaces IA,IB,…
  • 7.
    5 Steps toremember 1. Design the application with Interfaces IA,IB,… 2. Create concrete classes AImpl, BImpl,… to implement interfaces IA,IB,… Remember: use @Inject to mark the non-default constructor.
  • 8.
    5 Steps toremember 1. Design the application with Interfaces IA,IB,… 2. Create concrete classes AImpl, BImpl,… to implement interfaces IA,IB,… Remember: use @Inject to mark the non-default constructor. 3. Create AppClientModule to configure which implementation is bound to which interface
  • 9.
    5 Steps toremember 1. Design the application with Interfaces IA,IB,… 2. Create concrete classes AImpl, BImpl,… to implement interfaces IA,IB,… Remember: use @Inject to mark the non-default constructor. 3. Create AppClientModule to configure which implementation is bound to which interface 4. Create interface AppGinjector with the AppClientModule in the annotation @GinModules. @GinModules({AppClientModule.class, other modules …})
  • 10.
    5 Steps toremember 1. Design the application with Interfaces IA,IB,… 2. Create concrete classes AImpl, BImpl,… to implement interfaces IA,IB,… Remember: use @Inject to mark the non-default constructor. 3. Create AppClientModule to configure which implementation is bound to which interface 4. Create interface AppGinjector with the AppClientModule in the annotation @GinModules. @GinModules({AppClientModule.class, other modules …}) 5. Generate code for AppGinjector and use it private final AppGinjector injector = GWT.create(AppGinjector.class); AppPresenter aPres = injector.getAppPresenter(); aPres.bind(); RootPanel.get().add(aPres.getDisplay().asWidget());
  • 11.
    Step 1: Designan Interface public class ConfigPresenter extends WidgetPresenter<ConfigPresenter.Display>{ public interface Display extends NameAwareWidgetDisplay, WidgetDisplay { public HasClickHandlers getSaveClick(); public void updateConfig(Config config); } … }
  • 12.
    Step 1: Designan Interface public class ConfigPresenter extends WidgetPresenter<ConfigPresenter.Display>{ public interface Display extends NameAwareWidgetDisplay, WidgetDisplay { public HasClickHandlers getSaveClick(); public void updateConfig(Config config); } … } For gwt-dispatch developers: Normally, we create a Display interface as an inner interface of a Presenter class
  • 13.
    Step 2: Implementthe interface public class ConfigView extends Composite implements ConfigPresenter.Display { private VerticalPanel panel = new VerticalPanel(); private AppConstants constants; @Inject public ConfigView(AppConstants constants, AppMessages messages) { this.constants = constants; panel.addStyleName(AppCSS.C_config_container); panel.add(new HTML("<h1>Config view: comming soon<h1>")); initWidget(panel); } … }
  • 14.
    Step 2: Implementthe interface If the class has no default constructor, then a @Inject annotation is required. Otherwise, you will get a RuntimeException (“No @Inject or default constructor found for class …. ”) public class ConfigView extends Composite implements ConfigPresenter.Display { private VerticalPanel panel = new VerticalPanel(); private AppConstants constants; @Inject public ConfigView(AppConstants constants, AppMessages messages) { this.constants = constants; panel.addStyleName(AppCSS.C_config_container); panel.add(new HTML("<h1>Config view: comming soon<h1>")); initWidget(panel); } … }
  • 15.
    Step 3: Createclass AppClientModule public class AppClientModule extends AbstractPresenterModule { @Override protected void configure() { bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class); bind(PlaceManager.class).to(AppPlaceManager.class); bindPresenter(LoginPresenter.class, LoginPresenter.Display.class, LoginView.class); bindPresenter(MainPresenter.class, MainPresenter.Display.class, MainView.class); bindPresenter(AppPresenter.class, AppPresenter.Display.class, AppView.class); bind(LoginPresenterPlace.class).in(Singleton.class); bind(ContactsPresenterPlace.class).in(Singleton.class); … bind(LoginPresenter.class).in(Singleton.class); bind(LoginPresenter.Display.class).to(LoginView.class); } }
  • 16.
    Step 3: Createclass AppClientModule public class AppClientModule extends AbstractPresenterModule { @Override protected void configure() { bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class); bind(PlaceManager.class).to(AppPlaceManager.class); bindPresenter(LoginPresenter.class, LoginPresenter.Display.class, LoginView.class); bindPresenter(MainPresenter.class, MainPresenter.Display.class, MainView.class); bindPresenter(AppPresenter.class, AppPresenter.Display.class, AppView.class); bind(LoginPresenterPlace.class).in(Singleton.class); bind(ContactsPresenterPlace.class).in(Singleton.class); … bind(LoginPresenter.class).in(Singleton.class); bind(LoginPresenter.Display.class).to(LoginView.class); } } Don’t need to bind LoginPresenter and LoginPresenter.Display Because they are already “bind” above in the bindPresenter(…) See the implementation of the bindPresenter() in the next slide …
  • 17.
    Note: Implementation ofbindPresenter() public abstract class AbstractPresenterModule extends AbstractGinModule { protected <D extends Display> void bindPresenter( Class<? extends Presenter> presenter, Class<D> display, Class<? extends D> displayImpl ) { bind( presenter ).in( Singleton.class ); bindDisplay( display, displayImpl ); } protected <D extends Display> void bindDisplay( Class<D> display, Class<? extends D> displayImpl ) { bind( display ).to( displayImpl ); } … }
  • 18.
    Note: Implementation ofbindPresenter() public abstract class AbstractPresenterModule extends AbstractGinModule { protected <D extends Display> void bindPresenter( Class<? extends Presenter> presenter, Class<D> display, Class<? extends D> displayImpl ) { bind( presenter ).in( Singleton.class ); bindDisplay( display, displayImpl ); } protected <D extends Display> void bindDisplay( Class<D> display, Class<? extends D> displayImpl ) { bind( display ).to( displayImpl ); } … } DisplayImpl class is bound to Display interface
  • 19.
    Note: Implementation ofbindPresenter() Presenter is bound as Singleton. It means there is no new instance created when you invoke AppGinjector.getPresenter() public abstract class AbstractPresenterModule extends AbstractGinModule { protected <D extends Display> void bindPresenter( Class<? extends Presenter> presenter, Class<D> display, Class<? extends D> displayImpl ) { bind( presenter ).in( Singleton.class ); bindDisplay( display, displayImpl ); } protected <D extends Display> void bindDisplay( Class<D> display, Class<? extends D> displayImpl ) { bind( display ).to( displayImpl ); } … } DisplayImpl class is bound to Display interface
  • 20.
    Step 4: DefineAppGinjector interface @GinModules({ClientDispatchModule.class,AppClientModule.class}) public interface AppGinjector extends Ginjector { public AppPresenter getAppPresenter(); public PlaceManager getPlaceManager(); public EventBus getEventBus(); }
  • 21.
    Step 4: DefineAppGinjector interface List of modules. Each module class contains only one configure() method to specify which implementation is bound to which interface. @GinModules({ClientDispatchModule.class,AppClientModule.class}) public interface AppGinjector extends Ginjector { public AppPresenter getAppPresenter(); public PlaceManager getPlaceManager(); public EventBus getEventBus(); }
  • 22.
    Step 4: DefineAppGinjector interface List of modules. Each module class contains only one configure() method to specify which implementation is bound to which interface. A helper module provided by gwt-dispatch (just ignore it for now) @GinModules({ClientDispatchModule.class,AppClientModule.class}) public interface AppGinjector extends Ginjector { public AppPresenter getAppPresenter(); public PlaceManager getPlaceManager(); public EventBus getEventBus(); }
  • 23.
    Step 4: DefineAppGinjector interface List of modules. Each module class contains only one configure() method to specify which implementation is bound to which interface. A helper module provided by gwt-dispatch (just ignore it for now) @GinModules({ClientDispatchModule.class,AppClientModule.class}) public interface AppGinjector extends Ginjector { public AppPresenter getAppPresenter(); public PlaceManager getPlaceManager(); You create it public EventBus getEventBus(); } in step 3!
  • 24.
    Step 4: DefineAppGinjector interface List of modules. Each module class contains only one configure() method to specify which implementation is bound to which interface. A helper module provided by gwt-dispatch (just ignore it for now) @GinModules({ClientDispatchModule.class,AppClientModule.class}) public interface AppGinjector extends Ginjector { public AppPresenter getAppPresenter(); public PlaceManager getPlaceManager(); You create it public EventBus getEventBus(); } in step 3! Use whatever name you want!
  • 25.
    Step 4: DefineAppGinjector interface List of modules. Each module class contains only one configure() method to specify which implementation is bound to which interface. A helper module provided by gwt-dispatch (just ignore it for now) @GinModules({ClientDispatchModule.class,AppClientModule.class}) public interface AppGinjector extends Ginjector { public AppPresenter getAppPresenter(); public PlaceManager getPlaceManager(); You create it public EventBus getEventBus(); } in step 3! Use whatever name you want! Return type is important. Injector will return the instance basing on type.
  • 26.
    Step 5: UsingInjector in the EntryPoint public class App implements EntryPoint{ private final AppGinjector injector = GWT.create(AppGinjector.class); public void onModuleLoad() { AppPresenter aPres = injector.getAppPresenter(); aPres.bind(); RootPanel.get().add(aPres.getDisplay().asWidget()); PlaceManager placeManager = injector.getPlaceManager(); placeManager.fireCurrentPlace(); } }
  • 27.
    Step 5: UsingInjector in the EntryPoint GWT generates the implementation of AppGinjector at compile time public class App implements EntryPoint{ private final AppGinjector injector = GWT.create(AppGinjector.class); public void onModuleLoad() { AppPresenter aPres = injector.getAppPresenter(); aPres.bind(); RootPanel.get().add(aPres.getDisplay().asWidget()); PlaceManager placeManager = injector.getPlaceManager(); placeManager.fireCurrentPlace(); } }
  • 28.
    Step 5: UsingInjector in the EntryPoint GWT generates the implementation of AppGinjector at compile time public class App implements EntryPoint{ private final AppGinjector injector = GWT.create(AppGinjector.class); public void onModuleLoad() { AppPresenter aPres = injector.getAppPresenter(); aPres.bind(); RootPanel.get().add(aPres.getDisplay().asWidget()); PlaceManager placeManager = injector.getPlaceManager(); placeManager.fireCurrentPlace(); } } Here are all Interfaces. Their implementations are injected by GIN. But which implementation is bound to which Interface? => See AppClientModule .configure()
  • 29.
  • 30.
    Learn more Articles: • Google's MVP tutorial • Best Practices For Architecting Your GWT App session Projects: • Project google-gin • Project google-guice • Project gwt-dispatch • Project gwt-presenter • Project gwt-platform • A project implement MVP patterns based on gwt-dispatch, gin, guice • Apache Hupa – a GWT based webmail (using maven+junit+eclipse, gwt-dispatch, gwt- presenter, gin, guin). Highly recommended! • TeampScape – Another tutorial projects about gwt+gae, gwt-dispatch, gwt-presenter, datastore/jdo
  • 31.