2. 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
3. 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
4. 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
6. 5 Steps to remember
1. Design the application with Interfaces IA,IB,…
7. 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.
8. 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
9. 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 …})
10. 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());
11. 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);
}
…
}
12. 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
13. 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);
}
…
}
14. 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);
}
…
}
16. 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 …
19. 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
20. Step 4: Define AppGinjector interface
@GinModules({ClientDispatchModule.class,AppClientModule.class})
public interface AppGinjector extends Ginjector {
public AppPresenter getAppPresenter();
public PlaceManager getPlaceManager();
public EventBus getEventBus();
}
21. 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();
}
22. 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();
}
23. 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!
24. 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!
25. 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.
26. 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();
}
}
27. 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();
}
}
28. 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()