Hi, I'm trying to understand the way Anvil scopes ...
# squarelibraries
m
Hi, I'm trying to understand the way Anvil scopes work, and not being entirely familiar with Dagger's scopes, I think I'm getting a bit confused. What I'm trying to achieve at the moment is: • An
AppComponent
that's a singleton, holding a few singletons, including a
TaskRegistry
• A
TaskSubComponent
, scoped to a
TaskScope
, declared through Anvil with
@MergeSubcomponent(TaskScope::class)
, which I think might be a mistake. A few classes are bound to this scope through
@TaskScoped
(the Dagger/javax.inject annotation) and
@ContributesBinding(TaskScope::class
Now in my
TaskRegistry
, I'm trying to instantiate tasks (which have a bunch of dependencies, all bound to
TaskScope
). The way I'm trying to do this is by injecting in my
TaskRegistry
a
Provider<TaskSubComponent>
, and using this to instantiate new tasks. In my
AppComponent
, I'm declaring my sub-component as well (
fun taskSubComponent(): TaskSubComponent
). At build-time, Dagger complains that it can't provide the sub-component as it doesn't have a binding. I thought that's what
@MergeSubcomponent
was basically achieving, but I'm clearly misunderstanding it. What I'm doing seems to be quite close to the
LoggedInScope
in the sample, but it doesn't seem to be used anywhere so I'm not really sure what's going on there... Does anyone have any hint/documentation other than the readme?
r
I’d suggest to write this with plain Dagger to avoid any confusion. You seem to use Dagger in a wrong way. Mixing components like you do is a red flag to me. Anvil isn’t adding new features to Dagger in that sense. If Dagger has scope / component limitations, then Anvil has them, too. What Anvil allows you to do is contributing modules to a scope, but that doesn’t seem to be your issue. Compare that with the sample in the README, it’s basically a TLDR of what Anvil is doing https://github.com/square/anvil#anvil
m
Would you mind elaborating on mixing components being a red flag? (I really never used Dagger much and never needed scopes, so yeah I'm most likely doing something wrong - this is just what I understood from the scopes doc page)
r
You try to get access to objects from a subscope in an object tied to the parent scope. That’s the red flag. Objects in a subscope can safely inject types from the parent scope. You try to do it the other way.
m
Ha, got it, thanks.
Back to the drawing board then :-)
There's one thing I'm not sure I understand though - how can you ever instantiate anything from a subscope if you can't do that from an object tied to the parent scope? https://dagger.dev/dev-guide/subcomponents.html seems to be doing something similar to what I'm doing (although they don't have an actual example for the scopes...)
r
Reading your explanation again. You try to inject
Provider<TaskSubComponent>
. You can’t do that. To create a subcomponent you grab the parent component and then call the factory method
fun taskSubComponent(): TaskSubComponent
. You can’t inject a subcomponent.
👍 1
m
I ended up with a similar conclusion and injected a
TaskSubComponent.Factory
- I guess it's semantically equivalent?