Использование Dagger2 DispatchingAndroidInjector в многомодульном проекте - PullRequest
3 голосов
/ 06 мая 2020

У меня проблема при использовании Dagger в многомодульном проекте. Допустим, у нас есть три модуля.

  • core
  • newfeaturesmodule -> api project (": core")
  • oldfeaturesmodule -> api project (": newfeaturesmodule" )

Классы приложений имеют одинаковую иерархию. Проблема заключалась в том, что как newfeaturesmodule, так и oldfeaturesmodule используют метод AndroidInjector для внедрения действий. И в итоге получилось sh о том, что в модуле newfeaturesmodule нет фабрики инжекторов android. Проблема заключалась в том, что когда я вызываю первое приложение, вставляемое в newfeaturesmodule, все было в порядке. Затем был вызван дочерний метод oncreate класса приложения в oldfeaturesmodule, и он снова вызвал inject для приложения, но на этот раз он заменил инжекторы активности в oldfeaturemodule инжекторами активности в newfeaturemodule. Итак, я придумал собственное решение, подобное этому

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;
    }
}

Итак, у меня есть два вопроса

  • Есть ли способ объединить activityInjectorFactories в Кинжал?

  • И во-вторых, подходит ли мой подход для этого случая или у него есть недостатки? Можно ли это улучшить, предоставив эти зависимости карты из моего NewFeaturesModule, возможно, или чего-то еще?

(Примечание: версия Dagger - 2.27)

...