I've an issue when using Dagger in multi module project. Let's say we have three modules.
- core
- newfeaturesmodule -> api project(":core")
- oldfeaturesmodule -> api project(":newfeaturesmodule")
Application classes has same hierarchy either. The problem was both newfeaturesmodule and oldfeaturesmodule are using AndroidInjector method to inject activites. And it ended up with a crash saying activities on newfeaturesmodule has no android injector factory. The problem was when i call first application inject in newfeaturesmodule everything was just fine. And then child oncreate method of application class on oldfeaturesmodule called and it called inject for application again but these time it replaced the activity injectors on oldfeaturemodule with activity injectors on newfeaturemodule. So i came up with a custom solution like this
public abstract class CoreApp extends Application {
@Override
public void onCreate() {
super.onCreate();
CoreComponent component =
DaggerCoreComponent.builder().coreModule(new CoreModule()).build();
initDependencies(component);
}
public abstract void initDependencies(CoreComponent component);
}
public abstract class NewFeaturesApp extends CoreApp implements HasActivityInjector {
public NewFeaturesComponent newFeaturesComponent;
@Inject Map<Class<?>, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithClassKeys;
@Inject Map<String, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithStringKeys;
@Override
public void initDependencies(CoreComponent component) {
newFeaturesComponent = DaggerNewFeaturesComponent.builder().coreComponent(component).build();
newFeaturesComponent.inject(this);
keepAndroidInjectors(injectorFactoriesWithClassKeys, injectorFactoriesWithStringKeys);
initLegacyDependencies(newFeaturesComponent);
}
public abstract void keepAndroidInjectors(
Map<Class<?>, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithClassKeys,
Map<String, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithStringKeys);
public abstract void initLegacyDependencies(NewFeaturesComponent component);
}
public class OldFeaturesApp extends NewFeaturesApp {
public OldFeaturesComponent oldFeaturesComponent;
DispatchingAndroidInjector<Object> dispatchingAndroidInjector;
@Inject Map<Class<?>, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithClassKeys;
@Inject Map<String, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithStringKeys;
Map<Class<?>, Provider<AndroidInjector.Factory<?>>> newInjectorFactoriesWithClassKeys;
Map<String, Provider<AndroidInjector.Factory<?>>> newInjectorFactoriesWithStringKeys;
@Override
public void keepAndroidInjectors(
Map<Class<?>, Provider<AndroidInjector.Factory<?>>> newInjectorFactoriesWithClassKeys,
Map<String, Provider<AndroidInjector.Factory<?>>> newInjectorFactoriesWithStringKeys) {
this.newInjectorFactoriesWithClassKeys = newInjectorFactoriesWithClassKeys;
this.newInjectorFactoriesWithStringKeys = newInjectorFactoriesWithStringKeys;
}
@Override
public void initLegacyDependencies(OldFeaturesComponent component) {
oldFeaturesComponent = DaggerOldFeaturesComponent.builder()
.application(this)
.dependent(component)
.build()
.inject(this);
Map<Class<?>, Provider<AndroidInjector.Factory<?>>> mergedInjectorFactoriesWithClassKeys = new HashMap<>();
Map<String, Provider<AndroidInjector.Factory<?>>> mergedInjectorFactoriesWithStringKeys = new HashMap<>();
mergedInjectorFactoriesWithClassKeys.putAll(newInjectorFactoriesWithClassKeys);
mergedInjectorFactoriesWithClassKeys.putAll(injectorFactoriesWithClassKeys);
mergedInjectorFactoriesWithStringKeys.putAll(newInjectorFactoriesWithStringKeys);
mergedInjectorFactoriesWithStringKeys.putAll(injectorFactoriesWithStringKeys);
dispatchingAndroidInjector = DispatchingAndroidInjector_Factory.newInstance(
mergedInjectorFactoriesWithClassKeys, mergedInjectorFactoriesWithStringKeys);
}
public AndroidInjector<Object> androidInjector() {
return dispatchingAndroidInjector;
}
}
So i have two questions
Are there any way to merge activityInjectorFactories in Dagger?
And second, is my approach fine for this case or has it some downsides ? Could that be improved with providing these map dependencies from my NewFeaturesModule maybe, or something else ?
(Note: Dagger version is 2.27)