[Hilt] Question: How to create a subcomponent of a custom component that has a Builder
See original GitHub issueWe’re using Hilt in version 2.34.1-beta.
We have 2 components:
@LoggedUserScope
@DefineComponent(parent = SingletonComponent::class)
interface UserComponent {
@DefineComponent.Builder
interface Builder {
fun setUser(@BindsInstance user: User): Builder
fun setToken(@BindsInstance string: String): Builder
fun build(): UserComponent
}
}
@ProjectScope
@DefineComponent(parent = UserComponent::class)
interface ProjectComponent {
@DefineComponent.Builder
interface Builder {
fun setProject(@BindsInstance project: Project): Builder
fun build(): ProjectComponent
}
}
The UserComponent
, without ProjectComponent
works fine. We are able to get the instance using EntryPoint
. Also, when the ProjectComponent
has a parent set to SingletonComponent
, everything is OK. But we’d like to have them nested. A logged user can choose a project, but after logging out projects are not available.
With the above code the compiler screams that we need @Provide-annotated
method for the ProjectComponent.Builder
. As I understand it correctly, the ProjectComponent
needs to know the instance of UserComponent
to be initialized. How can it be provided? All samples we found are using a parent component without any parameters, so the compiler can instantiate it automagically.
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (5 by maintainers)
Top GitHub Comments
A scope annotation just tells you whether or not the object should be cached. If you don’t scope it, every time you ask for a
ProjectDataRepository
you’ll get a new instance. This doesn’t affect the parent/child relationship ofUserComponent
andProjectComponent
. (Note that it is really the components that have the relationship. I think it gets confusing because colloquially people will often use the scope and component names interchangeably to mean the same thing, but most of the time it is technically the components you should be referring to as the scope annotation really just controls caching within that component).Anyway, closing this now since it seems everything has been solved.
Not sure I followed that, but the
Builder
isn’t the parent of theProjectComponent
? Or do you mean that becauseUserComponent
is the parent, the childProjectComponent
should be able to be injected the same as the parent?In any case, you would need something like the following:
The requirement is that the code that injects the
ProjectComponent.Builder
has to be injected from the parentUserComponent
. If it is injected from somewhere else, like the HiltViewModelComponent
, then it won’t work. The reason injecting theUserComponent.Builder
works is because the parent is the HiltSingletonComponent
, so the parent is accessible from theViewModelComponent
sinceViewModelComponent
is a child ofSingletonComponent
.ViewModelComponent
is not a child ofUserComponent
however so that is why it does not work forProjectComponent.Builder
.