Inject into arbitrary Logic class that is not instanciated by Hilt

880 views Asked by At

I'm currently migrating an app from anko-sqlite to room as anko has been discontinued a long time ago. In the process of doing so I introduced a repository layer and thought I would try to introduce dependency injection to get references to the repository instances in all my classes.

Prior to this I used a singleton instance that I just shoved into my application classes companion object and accessed that from everywhere.

I managed to inject my repositories into Fragments, Workmanager and Viewmodels. But I do now struggle a bit to understand how they forsaw we should handle this with arbitrary logic classes.

For instance my workmanager worker calls a class that instantiates a list of "jobs" and those need access to the repository. The worker itself actually bearly even does need access to the repositories as all the work is abstracted away from it.

How can I make something like this work

class Job(val someExtraArgINeed: Int) {

@Inject
lateinit var someRepository: SomeRepository   // <= this should be injected when the job is instanciated with the constructor that already exists

}

For Activities and so forth we have special annotations @AndroidEntryPoint that makes this work. However, the documentation makes it unclear as to how we should get our instances from any other class that isn't an Android class. I understand that constructor injection is the recommended thing to use. But I do not think it would work here for me without an even more massive refactor required than this already would be.

1

There are 1 answers

3
Mehdi Yari On BEST ANSWER

If I understand your question correctly you can use hilt entry points like this

class CustomClass(applicationContext: Context) {

    @EntryPoint
    @InstallIn([/*hilt component that provide SomeRepository*/ApplicationComponent]::class)
    interface SomeRepositoryEntryPoint {
        fun provideSomeRepository(): SomeRepository
    }

    private val someRepository by lazy {
        EntryPointAccessors.fromApplication(applicationContext, SomeRepositoryEntryPoint::class.java).provideSomeRepository()
    }

    fun doSomething() {
        someRepository.doSomething()
    }

}