Nel progetto a cui sto lavorando, sto usando Guice e sto cercando di fare il più possibile con Dependency Injection. Tuttavia, c'è un piccolo intoppo; molti dei miei oggetti si basano su un oggetto Context
. Questo è un oggetto immutabile ma ha alcune informazioni che la maggior parte degli altri oggetti devono funzionare correttamente. Non cambia mai per le classi che lavorano tutte all'interno dello stesso Context
, ma la mia applicazione deve essere in grado di supportare diversi Context
s allo stesso tempo, nello stesso ambito. Posso pensare a tre modi per risolvere il mio problema:
-
Attualmente mi sono trovato a scrivere un sacco di codice con AssistedInject, che ha quasi sempre metodi come
Factory.create(Context c)
. Tutto il mio codice che dipende daContext
viene creato in questo modo, anche se sono altrimenti semplici. -
Sto iniziando a considerare l'utilizzo di
Provider
s e la modifica di ogni riga difactory.create(context)
inobj = provider.get(); obj.setContext(c);
ma non voglio fare affidamento sul mio codice per effettuare entrambe le chiamate, mi piace che il il compilatore si assicura che ogni oggetto abbia il suocontext
e checontext
non possa cambiare (non lo farà mai). -
La mia ricerca mi ha indirizzato a questa discussione: link L'idea di associare ogni
Context
a unchildInjector
che ha una rigabind(Context.class).toInstance(ContextFactory.makeInstance(args))
, ma non sono sicuro di come garantire che tutto stia usando l'iniettore figlio corretto. Sembra che potrebbe essere il migliore, ma a parte quel thread (che non è il mio scenario) non sono sicuro di come farlo, o se è giusto per la mia situazione.
Ecco un sscce di ciò che potrebbe essere fatto dall'opzione 3:
public class GuiceChildTest {
public static void main(String... args) {
Injector inj = Guice.createInjector(new ParentModule());
Injector fooChildOne = inj.createChildInjector(new FooModule(new Foo(10)));
Injector fooChildTwo = inj.createChildInjector(new FooModule(new Foo(20)));
Bar bar = fooChildOne.getInstance(Bar.class);
System.out.println(bar.baz());
bar = fooChildTwo.getInstance(Bar.class);
System.out.println(bar.baz());
}
private static class ParentModule extends AbstractModule {
@Override
protected void configure() {
}
}
private static class Bar {
private MyInterface intf;
@Inject
public Bar(MyInterface in) {
this.intf = in;
}
public int baz() {
return intf.doSomething();
}
}
private static class FooModule extends AbstractModule {
private Foo f;
public FooModule(Foo f) {
this.f = f;
}
@Override
protected void configure() {
bind(MyInterface.class).toInstance(f);
}
}
private static class Foo implements MyInterface {
private int i;
public Foo(int i) {
this.i = i;
}
@Override
public int doSomething() {
return i;
}
}
private static interface MyInterface {
int doSomething();
}
}