Wstrzykiwanie kolekcji klas za pomocą Guice
Próbuję wprowadzić rzeczy z Google Guice 2.0 i mam następującą strukturę:
FooAction implements Action
BarAction implements Action
Mam wtedy ActionLibrary z następującym konstruktorem:
ActionLibrary (List<Action> theActions)
Kiedy żądam instancji ActionLibrary z Guice, chciałbym, aby Guice zidentyfikował obie zarejestrowane klasy akcji (FooAction, BarAction) i przekazał je do konstruktora. Motywacją jest to, że gdy dodam trzecią akcję BazAction, będzie to tak proste, jak rejestracja to w Module i zostanie automatycznie dodany do listy w konstruktorze.
Czy to możliwe?2 answers
To, czego chcesz, to wielowątkowość . W szczególności, chcesz związać Set<Action>
(nie List
, ale {[3] } jest prawdopodobnie tym, czego naprawdę chcesz) w ten sposób:
Multibinder<Action> actionBinder = Multibinder.newSetBinder(binder(), Action.class);
actionBinder.addBinding().to(FooAction.class);
actionBinder.addBinding().to(BarAction.class);
Wtedy możesz @Inject
Set<Action>
gdziekolwiek.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-08 14:38:27
Pozwól, że pokażę Ci, co uważam za jeszcze lepszy sposób multibinding rzeczy. Jeśli chcesz, aby Action
S były wtyczkowe i pozwalały każdemu je dodawać, często przydatne jest zapewnienie prostego Module
dla kogoś, kto będzie używał, który ukrywa potrzebę utworzenia instancji Multibinder
. Oto przykład:
public abstract class ActionModule extends AbstractModule {
private Multibinder<Action> actionBinder;
@Override protected void configure() {
actionBinder = Multibinder.newSetBinder(binder(), Action.class);
configureActions();
}
/**
* Override this method to call {@link #bindAction}.
*/
protected abstract void configureActions();
protected final LinkedBindingBuilder<Action> bindAction() {
return actionBinder.addBinding();
}
}
Dlaczego tak jest lepiej? Pozwala na użycie ActionModule
z dowolnego miejsca, aby dodać więcej Action
za pośrednictwem standardowego interfejsu API. Myślę, że jest bardziej czytelny. Oto przykładowe użycie:
public final class MyStandardActionModule extends ActionModule() {
@Override protected void configureActions() {
bindAction().to(FooAction.class);
bindAction().to(BarAction.class);
// If you need to instantiate an action through a Provider, do this.
bindAction().toProvider(BazActionProvider.class);
// You can also scope stuff:
bindAction().to(MySingletonAction.class).in(Singleton.class);
}
}
Ten wzór użycie Module
do ukrycia multibindera jest używane w kodzie Guice. To trochę pracy z góry, ale utrzymuje porządek. Możesz również zrobić coś podobnego dla MapBinder
, jeśli potrzebujesz. Pamiętaj, że możesz utworzyć dowolną liczbę ActionModule
s, ile chcesz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-29 12:58:57