CustomView dependency injection with dagger 2 (within activity scope)

Viewed 11582

My question is similar to this.

So for instance, I have a LiveData implementation:

public class CustomLiveData extends LiveData<SomeEvent> {

    @Inject
    public CustomLiveData(@ActivityContext Context context) {
        //....
    }

}

that I want to inject into a custom view:

public class CustomView extends View {
   @Inject
   SomeApplicationProvider anyProvider;

   @Inject
   CustomLiveData dataProvider; 
   // Getting @com.di.qualifiers.ActivityContext  android.content.Context cannot be provided without an @Provides-annotated method. 
   // @com.di.qualifiers.ActivityContext android.content.Context is injected at com.repositories.CustomLiveData.<init>(context)
   // com.repositories.CustomLiveData is injected at com.ui.CustomView.dataProvider com.ui.CustomView is injected at 
   // com.di.ApplicationComponent.inject(view)

   public CustomView(Context context) { this(context, null); }
   public CustomView(Context AttributeSet attrs) { 
      super(context, attrs);

      // Works ok for application provider
      Application.getComponent(context).inject(this);
   }
}

And here is the rest of DI classes:

@ApplicationScope
@Component(
        modules = {AndroidInjectionModule.class,
                ActivityBuilder.class
        })

public interface ApplicationComponent extends AndroidInjector<MyApp> {

    void inject(MyApp application);

    void inject(CustomView view);

    @Component.Builder
    abstract class Builder extends AndroidInjector.Builder<MyApp> {

        public abstract ApplicationComponent build();
    }
}

@ActivityScope
@Module (subcomponents = MainActivitySubcomponent.class)
public abstract class ActivityBuilder {

    @Binds
    @IntoMap
    @ActivityKey(MainActivity.class)
    abstract AndroidInjector.Factory<? extends Activity>
    bindActivityInjectorFactory(MainActivitySubcomponent.Builder builder);

    //...

}


@Subcomponent(modules = {MainActivityModule.class})
public interface MainActivitySubcomponent extends AndroidInjector<MainActivity> {

    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {

    }
}

@ActivityScope
@Module
public class MainActivityModule {

    @Provides
    @ActivityContext
    public Context provideActivityContext(MainActivity activity) {
        return activity;
    }

    // Seems to be wrong or not enough!?
    @Provides
    public CustomLiveData provideCustomLiveData(@ActivityContext Context context) {
        return new CustomLiveData(context);
    }
}


@Qualifier
public @interface ActivityContext{
}

Note, that I don't get any compiler complaints if CustomLiveData is injected into MainActivity instead into the view. Thanks!

2 Answers
Related