Mit Dolch 2 versuche ich ein Singleton-Objekt an mehreren Orten in einem einzigen Bereich zu injizieren. Es scheint jedoch, dass meine Lösung stattdessen jedes Mal eine neue Instanz erstellt.Dolch 2 Singletons funktioniert nicht
In diesem Testprojekt habe ich eine MainActivity, die das DaggerModule initialisiert. Das DaggerModule stellt die Objekte Box und Cat zur Verfügung, wobei die Box Cat als Parameter verwendet. Ich nehme auch Cat in meiner MainActivity auf. Schließlich überprüfe ich die Referenzen der beiden injizierten Cat-Variablen (in der Box und in der MainActivity), aber sie sind nicht die gleiche Instanz.
Wenn ich provideCat() zweimal in meiner MainActivity stattdessen aufrufen, wird dieselbe Instanz bereitgestellt.
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;
}
}
Vielen Dank im Voraus!
Edit: Es funktioniert, wenn provideBox in einem Cat-Argumente und verwendet, dass die Box zu erstellen, statt Aufruf provideCat direkt aus 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);
}
Was ist der Unterschied zwischen provideCat im MainActivity Aufruf und es von innen provideBox im DaggerModule tun? Könnte es sein, dass der Dagger-Compiler das DaggerModule nicht genauso wie bei externen Klassen verarbeitet und die Annotationen nicht angewendet werden, wenn ich provideCat dort anrufe?
Der Grund dafür ist, dass das Instanzenmanagement von der Komponentenimplementierung und nicht vom Modul gehandhabt wird. Wenn Sie die Methode direkt aufrufen, wird sie nur wie jede andere Java-Methode aufgerufen, aber wenn Sie die Komponenten die Abhängigkeiten miteinander verbinden lassen, wird ein 'dagger.internal.ScopedProvider' verwendet, um sicherzustellen, dass es nur eine Instanz gibt. – gk5885
Auch für Typen, die '@ Inject'ed sind, können Sie einfach die Klasse (in diesem Fall' Cat' und 'Box') mit' @ Singleton' direkt annotieren und die '@ Providents'-Methoden vermeiden. – gk5885
Danke für die Info und Tipp! – Johe