Dependencies from two components in one activity

我的未来我决定 提交于 2019-12-04 12:15:45

问题


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!



来源:https://stackoverflow.com/questions/36352796/dependencies-from-two-components-in-one-activity

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