Andrew
Andrew

Reputation: 4712

Dagger hilt: Difference between annotating a class @Singleton and a provides function @Singleton

My question is pretty simple and straightforward: What is the difference between the two annotations / examples:

Example one

@Singleton
class MySingletonClass() {}

@Module
@InstallIn(FragmentComponent::class)
abstract class MyFragmentModule {
   @Provides
   fun provideMySingletonClass() = MySingletonClass()
}

Eaxmple two

class MySingletonClass() {}

@Module
@InstallIn(FragmentComponent::class)
abstract class MyFragmentModule {

   @Singleton
   @Provides
   fun provideMySingletonClass() = MySingletonClass()
}

The only difference I know is, that the second example gives me the following error:

error: [Dagger/IncompatiblyScopedBindings] FragmentC scoped with @dagger.hilt.android.scopes.FragmentScoped may not reference bindings with different scopes:

Does that mean, that the @Singleton annotation in example one is simply ignored?

Upvotes: 6

Views: 3387

Answers (1)

Jeff Bowman
Jeff Bowman

Reputation: 95654

In Example One, your @Singleton annotation is ignored, but only because you are calling the constructor yourself in your @Provides method. Because Dagger doesn't interact with your MySingletonClass constructor, it cannot read or use the annotation.

If your @Singleton class MySingletonClass had an @Inject constructor—even an empty one—then Dagger would be able to interact with it directly as long as you also delete the @Provides fun that would override the constructor detection. Once you've done that, the behavior of @Singleton would be the same in either syntax.


Regarding the error message "error: [Dagger/IncompatiblyScopedBindings] XXX scoped with @YYY may not reference bindings with different scopes": @Andrew The real problem here is that in Example Two you're trying to declare a @Singleton binding in a Module that you install in your FragmentComponent. @Singleton bindings can only happen in a @Singleton component, which in Hilt is SingletonComponent. I don't remember for sure, but I think your Example One (with the edits I described) would work with singleton behavior and without an error, because Dagger would automatically select the appropriate component in the hierarchy to install your MySingletonClass.

Upvotes: 7

Related Questions