Dagger 2 base class injections

♀尐吖头ヾ 提交于 2019-12-03 16:45:39

Theoretically, you can do it like this.

1.) Specify a child scope

@Scope
@Retention(RUNTIME)
public @interface PerActivity {
}

2.) Specify the parent component

@Singleton
@Component(modules={Module1.class, Module2.class)
public interface MyApplicationComponent {
    Dependency1 providesDependency1();
    Dependency2 providesDependency2();
}

3.) Specify the child component

@PerActivity
@Component(dependencies={MyApplicationComponent.class}, modules={Module3.class})
public interface MyBaseActivityComponent extends MyApplicationComponent {
    void inject(BaseActivity baseActivity);

    Dependency3 providesDependency3();
}

4.) Create your module

@Module
public class Module3 {
     @Provides
     @PerActivity
     public Dependency3 providesDependency3() {
         return new Dependency3();
     }
}

5.) Create Activity-level scoped component

public class BaseActivity extends AppCompatActivity {
    private MyBaseActivityComponent baseComponent;

    @Override
    public void onCreate(Bundle saveState) {
        super.onCreate(saveState);
        baseComponent = DaggerBaseActivityComponent.builder()
                    .applicationComponent(((MyApp)getApplication()).component())
                    .build();
    }

    public MyBaseActivityComponent baseComponent() {
        return baseComponent;
    }

    @Override
    public void onDestroy() {
        component = null;
        super.onDestroy();
    }
}

Please reply if it worked, previously I forgot to specify the dependencies in my Component and got compile errors, but it should work like this.

Also, if you need to specify a subcomponent for each Activity, then you can just specify the dependencies with provision methods in the BaseActivityComponent component...

@PerActivity
@Component(dependencies={MyBaseActivityComponent.class}, modules={Module4.class})
public interface MyActivityComponent extends MyBaseActivityComponent {
    public void inject(MyActivity myActivity);

    Dependency4 providesDependency4();
}

@Module
public class Module4 {
    @PerActivity
    @Provides
    public Dependency4 providesDependency4(Dependency3 dependency3) {
        return new Dependency4(dependency3);
    }
}

public class MyActivity extends MyBaseActivity {
    private MyActivityComponent component;

    @Override
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        component = DaggerMyActivityComponent.builder()
           .applicationComponent(((MyApp)getApplication()).component())
           .myBaseActivityComponent(baseComponent())
           .build();
    }

    @Override
    public void onDestroy() {
        component = null;
        super.onDestroy();
    }
}

EDIT: @Subcomponent works to replace component dependencies with subcomponent factory methods according to the docs only if you use the following pattern (aka, embedding the subcomponent within the parent component using a provision/factory method definition):

   @Singleton @Component
   interface ApplicationComponent {
     // component methods...

     RequestComponent newRequestComponent(RequestModule requestModule);
   }

Where

  @Subcomponent(modules={RequestModule.class})
  interface RequestComponent {
       RequestSomething requestSomething();
  }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!