Subby Subby - 22 days ago 7
Android Question

Modules with different Scopes

How do I make a Module which has an annotation, like @UserScope, dependent on another Module that's a @Singleton?

@Module(includes = {ApplicationModule.class})
public class JobManagerModule
{
private static final String TAG = JobManagerModule.class.getSimpleName();

@UserScope
@Provides
public JobManager providesJobManager(final Context context)
{
Log.d(TAG, "Providing JobManager");
final Configuration configuration = new Configuration.Builder(context).build();
return new JobManager(configuration);
}
}


Here, JobManagerModule provides using @UserScope but the ApplicationModule provides the Context object (which JobManagerModule needs) as a @Singleton.

This shows errors.

Answer

If you want to create a different Scope, then this scope must be a subcomponent of @Singleton.

Suppose you have ApplicationComponent annotated with @Singleton:

@Singleton
@Component(
        modules = ApplicationModule.class
)
public interface ApplicationComponent {

    JobManagerComponent provide(JobManagerModule jobManagerModule);
}

ApplicationModule provides Context:

@Module
public class ApplicationModule {
    protected final Application mApplication;

    public ApplicationModule(Application application) {
        mApplication = application;
    }

    @Provides
    @ApplicationContext
    public Context provideApplicationContext() {
        return mApplication;
    }
}

Notice, that ApplicationComponent must provide JobManagerComponent and Context is provided with @ApplicationContext annotation.

Now you create JobManagerComponent as a @Subcomponent of ApplicationComponent:

@UserScope
@Subcomponent(
        modules = JobManagerModule.class
)
public interface JobManagerComponent{
}

JobManagerModule:

@Module
public class JobManagerModule
{
    private static final String TAG = JobManagerModule.class.getSimpleName();

    @UserScope
    @Provides
    public JobManager providesJobManager(@ApplicationContext Context context)
    {
        Log.d(TAG, "Providing JobManager");
        final Configuration configuration = new Configuration.Builder(context).build();
        return new JobManager(configuration);
    }
}

Notice the removal of include from @Module annotation and Context annotated with @ApplicationContext

Creation of JobManagerComponent:

JobManagerComponent jobComponent = DaggerApplicationComponent.builder()
    .applicationModule(applicationModule)
    .build()
    .provide(new JobManagerModule());