My app is built with a Single Activity and it is feature-based multi-module. All UI is built using composable.
I want to create a custom scope for feature A. When the feature's journey is completed, its scope must be destroyed.
@Scope
@MustBeDocumented
@Retention(value = AnnotationRetention.RUNTIME)
annotation class MyCustomScope
component
@MyCustomScope
@DefineComponent(parent = SingletonComponent::class)
interface MyCustomComponent
@DefineComponent.Builder
interface MyCustomComponentBuilder {
fun provideEmployee(@BindsInstance employee: Employee?): MyCustomComponentBuilder
fun build(): MyCustomComponent
}
Employee interface
interface EmployeeInterface {
fun employee() : Employee
}
class EmployeeInterfaceImpl @Inject constructor(): EmployeeInterface {
override fun employee(): Employee {
return Employee()
}
}
Entry Point
@EntryPoint
@InstallIn(MyCustomComponent::class)
interface MyCustomEntryPoint {
fun getEmployee(): EmployeeInterface
}
Module
@Module
@InstallIn(MyCustomComponent::class)
interface EmployeeModule {
@MyCustomScope
@Binds
fun provideEmployeeInterface(employeeInterfaceImpl: EmployeeInterfaceImpl) : EmployeeInterface
}
Now using the employe in my viewmodel
@HiltViewModel
class AViewModel @Inject constructor(
private val person: Person,
private val componentManager: CustomComponentManager
) : ViewModel() {
init {
componentManager.setEmployee(Employee())
val employee = EntryPoints.get(componentManager, MyCustomEntryPoint::class.java).getEmployee()
Log.d(
"Test", "CVM Person: $person Hashcode: ${person.hashCode()} && Employee: $employee " +
"Hashcode: ${employee.hashCode()}"
)
}
}
SecondViewmodel
@HiltViewModel
class BViewModel @Inject constructor(
private val person: Person,
private val componentManager: CustomComponentManager
) : ViewModel() {
private val employee =
EntryPoints.get(componentManager, MyCustomEntryPoint::class.java).getEmployee()
init {
Log.d(
"Test", "DVM Person: $person Hashcode: ${person.hashCode()} && Employee: $employee " +
"Hashcode: ${employee.hashCode()}"
)
}
override fun onCleared() {
componentManager.invalidatedEmployee()
super.onCleared()
}
}
CustomComponentManager
@Singleton
class CustomComponentManager @Inject constructor(
private val componentBuilder:
MyCustomComponentBuilder
) :
GeneratedComponentManager<MyCustomComponent> {
private var component = componentBuilder
.provideEmployee(null)
.build()
fun setEmployee(employee: Employee) {
component = componentBuilder
.provideEmployee(employee)
.build()
}
fun invalidatedEmployee() {
component = componentBuilder
.provideEmployee(null)
.build()
}
override fun generatedComponent(): MyCustomComponent {
return component
}
}
Using the singleton annotation on the ComponentManager class makes the class singleton.
When I entered AViewModel I set the employee data as it is singleton hence I got the same employee instance on BViewModel.
My App Journey Home -> A Screen -> B Screen.
After completing the A and B screen journey and coming back to the home screen. Will Dagger hold the CustomComponentManager
instance?
If yes, I want to destroy its instance when I finish my A->B->Home screen journey.
How can I achieve this?
I have followed Hilt Multi Module and Dagger Multi Module.