Dependencies from two components in one activity

匿名 (未验证) 提交于 2019-12-03 01:33:01

问题:

I'm playing with Dagger-2 to figure how to integrate it in our existing application and I'm facing something which I can't understand or I'm doing wrong.

My situation :

3 API without any annotated constructor ( each one in its own file )

public class DbApi {    public void doSomething(String username, String password) {    } }  public class RestApi {     public void doSomething(String username, String password) {     } }  public class SocketApi {     public void doSomething(String username, String password) {     } }

3 Modules ( each one in its own file )

@Module public class DbModule {     @Provides     @Singleton     public DbApi getDbApi(){         return new DbApi();     } }  @Module public class RestModule {     @Provides     @Singleton     public RestApi getRestApi(){         return new RestApi();     } }  @Module public class SocketModule {     @Provides     @Singleton     public SocketApi getSocketApi(){         return new SocketApi();     } }

2 Components ( each one in its own file )

@Singleton @Component(modules = {DbModule.class}) public interface DbComponent {    void inject(SecondActivity activity); }  @Singleton @Component(modules = {RestModule.class, SocketModule.class}) public interface NetComponent {    void inject(MainActivity activity); }

I initialize the two components into my Aplication

public class MyApplication extends Application {  DbComponent dBComponent; NetComponent netComponent;  @Override public void onCreate() {     super.onCreate();     dBComponent = DaggerDbComponent.builder().build();     netComponent = DaggerNetComponent.builder().build(); }  public NetComponent getNetComponent() {     return netComponent; }  public DbComponent getdBComponent() {     return dBComponent; } }

With all this defined I use the NetComponent into one activity and the DbCompoment into a second one.

Into the first activity

public class MainActivity extends AppCompatActivity {  @Inject RestApi restApi; @Inject SocketApi socketApi;  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     //...     ((MyApplication) getApplication()).getNetComponent().inject(this);     //... } }

and into the second

public class SecondActivity extends AppCompatActivity {  @Inject DbApi dbApi;  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     //...     ((MyApplication) getApplication()).getdBComponent().inject(this);     //... } }

Up to here everything works fine and I got my stuff injected properlty in each activity. But then I have realised that RestApi and SocketApi were also required into the SecondActity so I tried to inject them into the activity and here I have doubts and issues.

I modify my NetComponent to add the following line

void inject(SecondActivity activity);

And I modify my SecondActivity

public class SecondActivity extends AppCompatActivity {  @Inject DbApi dbApi; @Inject RestApi restApi; @Inject SocketApi socketApi;  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     //...     ((MyApplication) getApplication()).getdBComponent().inject(this);     ((MyApplication) getApplication()).getNetComponent().inject(this);     //... } }

After those modifications compiling my project I have the following error

Error:(15, 10) error: com.example.guillaume.testdagger.RestApi cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method. com.example.guillaume.testdagger.SecondActivity.restApi [injected field of type: com.example.guillaume.testdagger.RestApi restApi]

Error:(16, 10) error: com.example.guillaume.testdagger.DbApi cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method. com.example.guillaume.testdagger.SecondActivity.dbApi [injected field of type: com.example.guillaume.testdagger.DbApi dbApi]

So my questions are :

  • Where this error comes from?
  • How can I use several components to inject fields into one activity
  • Am I doing this wrong and what will be the best way to organize components/modules in order to be able to reuse one compoment into an activity already containing another module
  • I can fix the error by adding and empty public constructor annotated with @Inject to my api classes but doing this I discoreved that all my fields will be injected into the SecondActivity regardless of the component used to invoke the inject method, is it the right way to do this.

回答1:

Ah...I share your pain. You can't inject two components into same Activity. At least I was not able to find how! :)

That was logical for me to try, as well, and I faced same problems.

You can resolve it with 2 approach:

  1. Use one big component for all injections (I am really agains that)
  2. Create one component for each Activity/place you want to inject something

So, instead of

@Singleton @Component(modules = {RestModule.class, SocketModule.class}) public interface NetComponent {    void inject(MainActivity activity); }

try with

@Singleton @Component(modules = {RestModule.class, SocketModule.class, DbModule.class}) public interface SecondActivityComponent {    void inject(SecondActivity activity); }

I found second one as cleanest solution.

If anybody has some other advice, I am ready to try it!



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!