https://kotlinlang.org logo
#koin
Title
# koin
c

Cedric Dupin

02/16/2023, 3:07 PM
Hello ! Is there a way to use "by inject()" inside an instance of an object created by deserialization ? Here is a dummy sample to reproduce my issue :
Copy code
interface LogInterface {
    fun logTag(tag: String)
}
class LogInterfaceImpl: LogInterface {
    override fun logTag(tag: String) {
        Log.d("LogInterface", "Tag : $tag")
    }
}

val logModule = module {
    single<LogInterface> { LogInterfaceImpl() }
}

class Logger(private val tag: String): KoinComponent{
    private val internalLogger: LogInterface by inject()

    fun log(){
        internalLogger.logTag(tag)
    }
}
data class LoggerTest(val logger : Logger)
Copy code
val loggerTest = LoggerTest(
    Logger("TEST_1")
)

loggerTest.logger.log() // display "TEST_1" in logs

val loggerTestJson = "{\"logger\":{\"tag\":\"TEST_2\"}}"
val loggerTest2: LoggerTest = Gson().fromJson(loggerTestJson, LoggerTest::class.java)

loggerTest2.logger.log() // throw a NPE :
Copy code
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object kotlin.Lazy.getValue()' on a null object reference
at Logger.getInternalLogger(line of "by inject()")
at Logger.log(line of "internalLogger.logTag(tag)")
I'm not very used to Koin, should I use scope / something else that "single" / ... ? Thanks !
p

Pedro Alberto

02/16/2023, 3:31 PM
why do you need such a situation ?
Why do you want the Logger to be a Json deserializable ?
c

Cedric Dupin

02/16/2023, 3:41 PM
Hi, the sample I provide here (the all "log" thing) is not my real usecase, it's just to illustrate my issue and to reproduce it easily. The summary is : I have to create an instance of a class by deserializing a json retrieved from the backend and I want to use "by inject()" inside this class.
p

Pedro Alberto

02/16/2023, 3:43 PM
but why to you want to use by inject in that class?
c

Cedric Dupin

02/16/2023, 3:45 PM
Because the implementation of the interface I want to inject come from another module.
e

Emanuel Moecklin

02/17/2023, 3:22 AM
you could use this helper function:
Copy code
inline fun <reified T> getKoinInstance() =
    object : KoinComponent {
        val value: T by inject()
    }.value
and then retrieve the logger like this:
Copy code
val internalLogger = getKoinInstances<LogInterface>()
c

Cedric Dupin

02/17/2023, 9:35 AM
It also throw a NPE. I manage to get it work by getting the instance inside the log() function :
Copy code
fun log() {
        val internalLogger: LogInterface = get()
        internalLogger.logTag(tag)
    }
6 Views