I am trying to use Dagger2 for DI, it works perfectly fine for Activity/Fragment related classes where there is a onCreate lifecycle event. Now I have a plain Java class which I want to be injected. Any ideas as to how to go about it would be appreciated. The code I have looks like this :
BasicMoviesUsecaseComponent.java -
@PerActivity
@Component(dependencies = AppComponent.class, modules = BasicMoviesUsecasesModule.class)
public interface BasicMoviesUsecasesComponent {
void inject(PaymentsManager paymentsManager);
}
DatabaseModule.java -
@Module
public class DatabaseModule {
@Provides @Singleton
Realm provideRealmInstance(Context context) {
return Realm.getInstance(context);
}
@Provides @Singleton
DatabaseProvider provideDatabaseInstance(Realm realm) {
return new DatabaseProvider(realm);
}
@Provides @Singleton
SharedPreferences provideSharedPrefs(Context context) {
return context.getSharedPreferences(context.getPackageName()+"_prefs", Context.MODE_PRIVATE);
}
@Provides @Singleton
SharedPreferencesManager provideSharedPreferencesManager(SharedPreferences sharedPreferences) {
return new SharedPreferencesManager(sharedPreferences);
}
@Provides @Singleton
PaymentsManager providePaymentsManager(SharedPreferencesManager sharedPreferencesManager) {
return new PaymentsManager(sharedPreferencesManager);
}
}
AppComponent.java -
@Singleton
@Component(modules = {
ApplicationModule.class,
DomainModule.class,
DatabaseModule.class
})
public interface AppComponent {
Bus bus();
Realm realm();
DatabaseProvider dbProvider();
SharedPreferencesManager sharedPreferencesManager();
}
Here is the class I need to inject the SharedPreferencesManager into and I am unable to do so :
MyManager.java -
private class MyManager {
private SharedPreferencesManager manager;
@Inject
MyManager(SharedPreferencesManager manager){
this.manager = manager;
}
private void initializeDependencyInjector() {
BMSApplication app = BMSApplication.getInstance();
DaggerBasicMoviesUsecasesComponent.builder()
.appComponent(app.getAppComponent())
.basicMoviesUsecasesModule(new BasicMoviesUsecasesModule())
.build().inject(PaymentsManager.this);
}
}
How do I call initializeDependencyInjector() ?
You should generally use constructor injection whenever possible. The call to
component.inject(myObject)
is mostly to be used for objects which you can not instantiate yourself (like activities or fragments).Constructor injection is basically what you already did:
Dagger will create the object for you and pass in your
SharedPreferencesManager
. There is no need to call init or something similar.The real question is how to obtain an object of
MyManager
. To do so, again, dagger will handle it for you.By annotating the constructor with
@Inject
you tell dagger how it can create an object of that type. To use it, just inject it or declare it as a dependency.Or just add a getter to a component (as long as
SharedPreferenceManager
can be provided,MyManager
can also be instantiated):