Utilizzando Dagger 2, sto provando a iniettare un oggetto singleton in più posizioni in un singolo ambito. Tuttavia, sembra che la mia soluzione crei invece una nuova istanza ogni volta.Daga 2 singleton non funzionanti
In questo progetto di prova, ho un MainActivity che inizializza il DaggerModule. DaggerModule fornisce gli oggetti Box e Cat, con Box che accetta Cat come parametro. Prendo anche Cat nella mia MainActivity. Infine, controllo i riferimenti di entrambe le variabili Cat iniettate (rispettivamente nel Box e nel MainActivity), ma non sono la stessa istanza.
Se si chiama providCat() due volte nel mio MainActivity, viene fornita la stessa istanza.
MainActivity:
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerModule daggerModule = new DaggerModule();
DaggerComponent daggerComponent = Dagger_DaggerComponent.builder()
.daggerModule(daggerModule).build();
// Same Cat instance returned.
Cat cat1 = daggerComponent.provideCat();
Cat cat2 = daggerComponent.provideCat();
Log.d("=== cat1: ", cat1.toString());
Log.d("=== cat2: ", cat2.toString());
// Different Cat instance returned. Why?
Box box = daggerComponent.provideBox();
Log.d("=== box cat: ", box.getCat().toString());
}
}
@Module
public class DaggerModule {
@Provides
@Singleton
public Cat provideCat() {
return new Cat();
}
@Provides
@Singleton
public Box provideBox() {
return new Box(provideCat());
}
}
@Singleton
@Component(modules = { DaggerModule.class })
public interface DaggerComponent {
Cat provideCat();
Box provideBox();
}
public class Cat {
@Inject
public Cat() {
}
}
public class Box {
private Cat mCat;
@Inject
public Box(Cat cat) {
mCat = cat;
}
public Cat getCat() {
return mCat;
}
}
Grazie in anticipo!
Edit: Funziona se provideBox prende in un argomento del gatto e lo utilizza per creare la sicurezza, invece di chiamare provideCat direttamente da provideBox.
// Doesn't work, new Cat instance created.
@Provides
@Singleton
public Box provideBox() {
return new Box(provideCat());
}
vs
// Works, same singleton injected.
@Provides
@Singleton
public Box provideBox(Cat cat) {
return new Box(cat);
}
Qual è la differenza tra chiamare provideCat nel MainActivity e farlo dall'interno provideBox nel DaggerModule? Potrebbe essere che il compilatore Dagger non elabora DaggerModule nello stesso modo in cui lo fa con le classi esterne e le annotazioni non vengono applicate se chiamo providCat?
Il motivo per cui il comportamento è diverso è che la gestione dell'istanza viene gestita dall'implementazione del componente, non dal modulo. Quando invochi direttamente il metodo, lo chiamerai come qualsiasi altro metodo Java, ma quando lascerai che il componente unisca le dipendenze userà un 'dagger.internal.ScopedProvider' per assicurarti che ci sia una sola istanza. – gk5885
Inoltre, per i tipi 'Inject'ed, puoi semplicemente annotare la classe (in questo caso' Cat' e 'Box') con' @ Singleton' direttamente ed evitare del tutto i metodi '@ Provides'. – gk5885
Grazie per le informazioni e la mancia! – Johe