https://kotlinlang.org logo
m

Mark

08/16/2021, 4:02 AM
Any thoughts on this approach (companion object of interface implementing interface) to inject an instance to be used throughout app?
Copy code
// common module
interface Brand {
    val foo: String // plus lots more properties and funs

    // implement Brand so usage like Brand.foo instead of Brand.INSTANCE.foo
    companion object : Brand {
        // this must be set very early in Application.onCreate()
        // why not use DI? Because sometimes we need access to Brand before DI has finished setting up
        lateinit var INSTANCE: Brand

        override val foo: String
            get() = INSTANCE.foo
    }
}
    
// brand module (dependency on common module)
// different brand modules for different product flavors
object ActualBrand : Brand {
    override val foo: String
        get() = "actual brand"
}

fun Brand.Companion.init() {
    INSTANCE = ActualBrand
}

// app module (dependencies on brand and common modules)
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Brand.init() // note: we do not need to hardcode ActualBrand
        // proceed to DI initialisation
    }
}
t

Tomasz Krakowiak

08/16/2021, 4:07 AM
Why not inject brand via DI, if you use one? Or maybe make it property of an Application?
m

Mark

08/16/2021, 4:08 AM
I need it during DI initialisation.
Application
not always available
Hmm, just trying out the code, and the problem is that
Application.onCreate()
is being called too late. I’m using Android AppInitializers which are triggered earlier, so next step is to investigate: https://proandroiddev.com/app-startup-under-the-hood-with-koin-library-example-380e188568ad But still, I’m interested in general thoughts about implementing an interface with the interface’s companion object.
t

Tomasz Krakowiak

08/16/2021, 4:47 AM
Maybe having them both in DI and Application property would be solution? I'm not sure what technologies you're using and how they work (long time since I coded anything for android), but I would definitely try to avoid having something that should be Application scope as global.
m

Mark

08/16/2021, 4:48 AM
Right, I don’t have any intention to have an Application property like that.
c

Colton Idle

08/16/2021, 1:53 PM
Personally, I would skip the initializer library and do everything in oncreate.
m

Mark

08/16/2021, 1:55 PM
I believe
Application.onCreate()
occurs after
ContentProvider
initialisation
c

Colton Idle

08/16/2021, 1:57 PM
Correct. Just stop using CP init. And disable other libraries from doing it (like firebase)
4 Views