GinMapBinder
allows you to incrementally build a binding to a java.util.Map
, so the way to use it is to get a Map
injected into your object. You'll find a complete example in Guice's MapBinder
javadoc, GinMapBinder
works the same.
To answer your questions:
Is this the way to go and solve my problems?
It could: if you inject a Map<String, Provider<MyView>>
with the keys being the user's role. If you have only two such roles, you also simply inject two Provider
s, and chose the one to get()
depending on the user's role. (see also below)
That's not how I'd do it though. I'd rather use a combination of deferred-binding (to generate distinct permutations for normal and admin users), with a property-provider to choose the right permutation at runtime, and dynamic host page (to pass the admin information from the server to the client before the client starts).
You'd use deferred-binding to choose which Ginjector to use (using a factory and <replace-with>
rules); Ginjectors would be identical (same methods, inherited from a base interface) except for the @GinModules
; and thus you can have a GinModule
for normal users and another one for admin users, each binding the MyView.class
to a distinct implementation class.
Can anybody give an example explaining how to use this and how to select the different injections at runtime?
Build a map binding user roles to view implementations:
GinMapBinder<String, MyView> mapBinder =
GinMapBinder.newMapBinder(binder(), String.class, MyView.class);
mapBinder.addBinding("normal").to(MyViewImplNormal.class);
mapBinder.addBinding("admin").to(MyViewImplAdmin.class);
Then inject it along with the user's role:
@Inject MyPresenter(@Named("user.role") String userRole,
Map<String, Provider<MyView>> views) {
And choose the appropriate view depending on the user's role:
// TODO: handle the case where the map has no value for the user role
this.view = views.get(userRole).get();
…
The alternative I was talking about:
bind(MyView.class).annotatedWith(named("user.normal")).to(MyViewImplNormal.class);
bind(MyView.class).annotatedWith(named("user.admin")).to(MyViewImplAdmin.class);
…
@Inject MyPresenter(@Named("user.isAdmin") boolean isAdmin,
@Named("user.normal") Provider<MyView> normalView,
@Named("user.admin") Provider<MyView> adminView) {
this.view = isAdmin ? adminView.get() : normalView.get();
…