I’ve written some time ago about Dagger 2.
However, I still don’t understand every nook and cranny.
In particular, the @Singleton
annotation can be quite misleading as user Zhuiden was kind enough to point out:
If you create a new ApplicationComponent each time you inject, you will get a new instance in every place where you inject; and you will not actually have singletons where you expect singletons. An ApplicationComponent should be managed by the Application and made accessible throughout the application, and the Activity should have nothing to do with its creation.
After a quick check, I could only agree.
The Singleton pattern is only applied in the context of a specific @Component
, and one is created each time when calling:
DaggerXXXComponent.create();
Thus, the only problem is to instantiate the component once and store it in a scope available from every class in the application. Guess what, this scope exists: only 2 simple steps are required.
- Extend the
Application
class and in theonCreate()
method, create a newXXXComponent
instance and store it as a static attribute.public class Global extends Application { private static ApplicationComponent applicationComponent; public static ApplicationComponent getApplicationComponent() { return applicationComponent; } @Override public void onCreate() { super.onCreate(); applicationComponent = DaggerApplicationComponent.create(); } }
- The next step is to hook into the created class into the application lifecycle in the Android manifest:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ch.frankel.todo"> <application android:name=".shared.Global"> ... </application> </manifest>
At this point, usage is quite straightforward. Replace the first snippet of this article with:
Global.getApplicationComponent();
This achieves real singletons in Dagger 2.