google / dagger

A fast dependency injector for Android and Java.
https://dagger.dev
Apache License 2.0
17.42k stars 2.01k forks source link

app bundle dynamic feature module #1251

Closed TadejZupancic closed 3 years ago

TadejZupancic commented 6 years ago

I had two separate applications, Dagger work fine if I run them separately. I am trying now to add the activities from second application as a dynamic feature module. When I try to open the activity that is in the dynamic feature module, I get: java.lang.IllegalArgumentException: No injector factory bound for Class<the activity I am trying to open>

Is this already supported? It looks like it uses only configuration from the base module and therefore does not know how to inject the activities, fragments... in the dynamic feature module.

Maybe I just have to change the configuration to be also able to inject components in the dynamic feature module, but I can't find anything about this anywhere.

ronshapiro commented 6 years ago

Perhaps the original application needs to be set up to be able to inject the activity from the dynamic feature module?

TadejZupancic commented 6 years ago

Yes, probably. Main module does not depend on the dynamic feature module, so I can't manually add the dynamic module activities to be injected. At least I haven't found a way to do so yet.

meecha commented 5 years ago

It might mot be the best answer, also It's not using android injector, But I have approach of using Dagger 2 to be able using component cross split feature module

I answer it on here https://github.com/googlesamples/android-instant-apps/issues/48#issuecomment-431793333

lincleejun commented 5 years ago

We faced the same issue I could provide a way to resolve this problem. there have a App and multiple dynamic feature module activity which in dynamic feature cannot be injected because of AndroidInjection find dependency from Application. but activity were in dynamic feature, when the compile time main module could not generate any injection code relate with this activity. so we provide a library similar as AndroidInjection

so i provide another AndroidInjection called DynamicCompatInjection, methods all like AndroidInjection. but inject method like this public static void inject(DynamicInjectable dynamicnjectable) and also provide a interface like HasActivityInjector

public interface HasDynamicInjector {
   // name - means dynamic feature name
    AndroidInjector<Activity> getDynamicInjector(String name);

}

at any dynamic feature module, must provide injector if you need to inject which like this

    @Provides
    @IntoMap
    @StringKey("dynamic_feature_a")
    public static AndroidInjector.Factory<? extends Activity> provideFactory() {
        return instance -> someReflection().androidInjector();
    }

util now everything could work,

in our activity which in dynamic feature, we just need to write

   public class DemoActivity extends AppCompatActivity implements DynamicInjectable {
    @Override
    public String getModuleName() {
        return "dynamic_feature_a";
    }
}

if you want to auto inject add some code in

ActivityLifecycleCallbacks {
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
     if (activity instance of DynamicInjectable) {
     DynamicCompatInjection.inject((DynamicInjectable) activity);
    }
}
}

everything were done.

TadejZupancic commented 5 years ago

Thank you. For now I moved back to having two separate applications, but it will come handy for the future, when the dynamic feature modules come out of beta.

claudiu-accenture commented 5 years ago

@lincleejun Any chance you could provide a link to the implementation or maybe elaborate a bit more, I'm not sure how everything ties together. Mainly what should go in the DynamicCompatInjection.inject() method and where should the dynamic feature module added to the main graph.

meecha commented 5 years ago

@claudiu-accenture I have a link but it's on bitbucket, in my POC at that time just for exchanging view and inflate them from different module in the upper module dependency,

I have flight and hotel module that being inflated on base module, the dependency already filled when application onCreate.

ronshapiro commented 5 years ago

This is a helpful blogpost on multi-module apps using Dagger: https://medium.com/androiddevelopers/dependency-injection-in-a-multi-module-project-1a09511c14b7

Unfortunately it doesn't use dagger.android, and I'm not sure how best to do that yet either.

meecha commented 5 years ago

if you want to use dagger android, you can refer to this blog post. https://medium.com/@star_zero/dynamic-feature-module%E3%81%A8dagger-b6332098ab70

claudiu-accenture commented 5 years ago

Thanks a lot @meecha, that guide really helped me set it up, by creating a custom AndroidInjector and forwarding the requested injection either to base Injector or to other Injectors set by the external feature modules, also helped understand dagger a bit better. Thanks again!

Frank1234 commented 5 years ago

To use both regular feature modules and dynamic ones, one can follow this principle, without dagger-android: https://blog.q42.nl/dynamic-feature-and-regular-modules-using-dagger2-12a7edcec1ff

Chang-Eric commented 3 years ago

There's also this guide as well https://developer.android.com/training/dependency-injection/dagger-multi-module#dagger-dfm and https://developer.android.com/training/dependency-injection/hilt-multi-module#dfm for Hilt.

I'm going to close this for now since I don't think there is anything specific we plan to do in Dagger for this beyond the advice given there.