Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger 2 Singleton Component Depend On Singleton

I've got a strange problem here, and I'm not quite sure why what I'm doing isn't allowed. I've got the following modules:

@Module
public final class AppModule {
  private Context mContext;

  @Provides
  @Singleton
  @AppContext
  public Context provideContext() { return mContext; }
}

@Module
public final class NetModule {
  @Provides
  @Singleton
  public OkHttpClient provideOkHttp() {
    return new OkHttpClient.Builder().build();
  }
}

For various reasons, I don't want to have these two modules in the same component (basically due to my project structure). So I tried to create the following components:

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
  @AppContext Context appContext();
}

@Singleton
@Component(dependencies = AppComponent.class, modules = NetModule.class)
public interface NetComponent {
  Retrofit retrofit();
}

But when I try to compile this, I get the following error message:

Error:(12, 1) error: This @Singleton component cannot depend on scoped components: @Singleton com.myapp.service.dagger.AppComponent

I understand why depending on different scopes would be bad and disallowed. But why is Singleton depends-on Singleton not allowed? This feels like it should work, since all I'm doing is declaring sibling components. What am I missing?

like image 640
tmtrademark Avatar asked Sep 26 '16 17:09

tmtrademark


People also ask

How do you add a dagger dependency?

In order to use dependency injection with the help of dagger 2 libraries, we need to add it's dependency. Go to Gradle Scripts > build. gradle(Module: app) and add the following dependencies. After adding these dependencies you need to click on Sync Now.

What does @singleton annotation do?

The @Singleton annotation is used to declare to Dagger that the provided object is to be only initialized only once during the entire lifecycle of the Component which uses that Module.

How does a dagger work internally?

Dagger generates code similar to what you would have written manually. Internally, Dagger creates a graph of objects that it can reference to find the way to provide an instance of a class. For every class in the graph, Dagger generates a factory-type class that it uses internally to get instances of that type.


1 Answers

Because your NetComponent component depends on your AppComponent component, they cannot have the same scope. Scopes are used to annotate lifecycles, and because NetComponent depends on AppComponent, they don't have the same lifecycle. AppComponent could potentially live longer than NetComponent, because it's a part of the actual build process of NetComponent. NetComponent couldn't exist without AppComponent, but not the other way around.

You could add your own custom scope and apply that to your NetComponent and NetModule, that would fix it.

like image 171
ootinii Avatar answered Sep 28 '22 04:09

ootinii