14

I am trying to compile https://github.com/svenjacobs/android-dagger2-example but I am running into an error related to unscoped component depending on scoped components. (Android Studio 1.1, Gradle 2.2.1). Also if anyone knows of other Dagger2 Android examples WITH FRAGMENTS I would like to know about them.

UPDATE: Here is another example one very basic with fragments: https://github.com/gk5885/dagger-android-sample

/Users/Mac1/android-dagger2-example-master/app/src/main/java/com/svenjacobs/dagger2/ActivityComponent.java
Error:(15, 1) error: com.svenjacobs.dagger2.ActivityComponent (unscoped) cannot depend on scoped components:
@Singleton com.svenjacobs.dagger2.ApplicationComponent
Error:Execution failed for task ':app:compileDebugJava'.
> Compilation failed; see the compiler error output for details.

Here is the file ActivityComponent which is apparently not scoped:

import dagger.Component;

/**
 * Component for all activities.
 *
 * @author Sven Jacobs
 */
@Component(dependencies = ApplicationComponent.class,
       modules = {
               MainActivityModule.class,
               AModule.class,
               BModule.class
       })
interface ActivityComponent extends AFragment.Injector, BFragment.Injector  {

    void inject(MainActivity activity);

    void inject(AnotherActivity activity);
}

And here is the scoped component:

package com.svenjacobs.dagger2;

import javax.inject.Singleton;

import dagger.Component;

/**
 * Application-wide dependencies.
 *
 * @author Sven Jacobs
 */
@Singleton
@Component(modules = ApplicationModule.class)
interface ApplicationComponent {

void inject(Dagger2Application application);

/**
 * Provides dependency for sub-components
 */
SomeApplicationDependency someApplicationDependency();
  }
Get Smarter
  • 181
  • 2
  • 2
  • 9

2 Answers2

16

You need to provide a scope for the ApplicationComponent. This doesn't necessarily have to be @Singleton, since Dagger 2 allows you to define your own scopes using the @Qualifier annotation on an interface.

@Scope
public @interface CustomScopeName {
}

You could then use it like so:

@CustomScopeName
@Component(dependencies = ApplicationComponent.class,
   modules = {
           MainActivityModule.class,
           AModule.class,
           BModule.class
   }) .......

I think the reason you aren't allowed to use a scoped dependency in an unscoped component is to prevent Singletons from depending on non-Singleton objects and prevent cyclic dependencies.

fakataha
  • 785
  • 6
  • 31
3

Sometime during the development of Dagger 2.0 the behaviour was changed and scoping of components became more strict. See this discussion. Because my sample projects relies on the SNAPSHOT release of Dagger 2.0 it broke.

As atamakosi said and which is also explained here pretty well you need to add a custom scope to the ActivityComponent, for example @PerActivity.

Community
  • 1
  • 1
Sven Jacobs
  • 6,278
  • 5
  • 33
  • 39