I'm in process of moving PeopleInSpace KMP sample ...
# koin
j
I'm in process of moving PeopleInSpace KMP sample over to use Koin Annotations.....I'm probably missing something but am getting
Missing Definition type 'io.ktor.client.engine.HttpClientEngine'
despite having following (and similar for other platforms)....not certain this is correct approach?
Copy code
@Module
actual class NativeModule {
    @Single
    fun httpClientEngine(): HttpClientEngine = Java.create()
}
The common code includes the following
Copy code
@Module(includes = [CommonModule::class, NativeModule::class])
class AppModule

@Module
expect class NativeModule
βœ… 1
πŸš‘ 1
also have following in common code
Copy code
@Module
@ComponentScan("com.surrus.common")
class CommonModule {
    @Single
    fun json() = Json { isLenient = true; ignoreUnknownKeys = true }

    @Single
    fun httpClient(httpClientEngine: HttpClientEngine, json : Json) = createHttpClient(httpClientEngine, json, true)
}
a
I don't see missing part. What gives you generated code?
j
I think I messed up my expect/actual for
NativeModule
(though fixing it here and seem to still see same issue)....will take a look at generated code
now I have
Copy code
@Module
expect class NativeModule {
    fun httpClientEngine(): HttpClientEngine
}
and for example
Copy code
@Module
actual class NativeModule {
    @Single
    actual fun httpClientEngine(): HttpClientEngine = Android.create()
}
a
ok
is it working now?
j
so, I got past that error by adding
@Single
also in expect class
Copy code
@Module
expect class NativeModule {
    @Single
    fun httpClientEngine(): HttpClientEngine
}
but getting following now
Copy code
Expected class 'expect class NativeModule : Any' does not have default constructor.
(in generated code)
Copy code
public val com_surrus_common_di_AppModule : Module get() = module {
	includes(com.surrus.common.di.CommonModule().module,com.surrus.common.di.NativeModule().module)
}
public val com.surrus.common.di.AppModule.module : org.koin.core.module.Module get() = com_surrus_common_di_AppModule
changes made so far in following branch fwiw https://github.com/joreilly/PeopleInSpace/tree/koin-annotations
I also just tried adding default constructor explicitly which is seemingly required for expect/actual classes if that's needed ...for example
Copy code
@Module
expect class NativeModule() {
    @Single
    fun httpClientEngine(): HttpClientEngine
}

@Module
actual class NativeModule actual constructor() {
    @Single
    actual fun httpClientEngine(): HttpClientEngine = Android.create()
}
but now get
Copy code
None of the following candidates is applicable:
val AppModule.module: Module
val CommonModule.module: Module
re.
module
in following
Copy code
includes(com.surrus.common.di.CommonModule().module,com.surrus.common.di.NativeModule().module)
just updated branch with those last changes
could also perhaps be something I'm missing in ksp setup
using
2.0.0-Beta1
of koin annotations btw
a
πŸ€”
need to check against current examples apps yes https://github.com/InsertKoinIO/KMP-App-Template/
this one is outdated already πŸ™„
I will look at your branch πŸ‘
j
Is there an example where
NativeModule
has it's own functions (not relying only on component scan etc)?
j
but that one doesn't include it's own functions?
directly at least
a
no, I scan for components
j
not sure if I can use that approach for creating that HttpClientEngine instance for example....
a
don"t know yet
finishing a bunch of CFP right now ^^
j
yeah, have a few of those to get done this weekend as well πŸ˜ƒ
πŸ˜„ 1
I see following in KMP-App-Template project which isn't there in case of PeopleInSpace for some reason....
that for example includes
NativeModule.module
fwiw I'm getting errors in generated code if I update KMP-App-Template to Kotlin 2.0.21 and related dependencies (including 2.0.0-Beta1 of koin-annotations
d
to me it sounds like issue I reported here: https://kotlinlang.slack.com/archives/C67HDJZ2N/p1729800476061049 it seems that Koin annotations can’t work with Kotlin 2.0, somehow it can’t link generated modules
a
Koin Annotations 2.0 should do the work, no? is there an issue?
yes, sounds like the same issue on new KSP πŸ‘ I'm on it
πŸ‘ 1
Will push Beta2 to fix the actual/expect generation fix - https://github.com/InsertKoinIO/koin-annotations/pull/189/files
@John O'Reilly I'm checking the patch locally on PeopleInSapce
πŸ‘ 1
@Dusan Stefanovic I've checked your PR + my patch on KMP App Template πŸ‘
Ci seems to build πŸ’ͺ
πŸ‘ 1
j
@arnaud.giuliani I'm getting internal error it seems when building compose for desktop client in that branch.....the ios and android clients are also not showing info but I haven' t looked in to that properly yet
Copy code
rg.jetbrains.kotlin.backend.common.CompilationException: Back-end: Please report this problem <https://kotl.in/issue>
/Users/joreilly/dev/github/PeopleInSpace/common/build/generated/sqldelight/code/PeopleInSpaceDatabase/commonMain/com/surrus/peopleinspace/db/PeopleInSpaceQueries.kt:-1:-1
Details: Internal error in file lowering: java.lang.IllegalStateException: should not be called
(I did a clean first)
using https://github.com/joreilly/PeopleInSpace/tree/koin-annotations branch (has your changes merged in to it now)
ah, I think
AndroidSqliteDriver
etc needs to be wired up still
I'll update that here.....not sure about compose for desktop one though....perhaps also related
I've tried to wire up
PeopleInSpaceDatabaseWrapper
(changes pushed to that branch) but getting following.
Copy code
e: [ksp] --> Missing Definition type 'com.surrus.common.di.PeopleInSpaceDatabaseWrapper' for 'com.surrus.common.repository.PeopleInSpaceRepository'. Fix your configuration to define type 'PeopleInSpaceDatabaseWrapper'.
I have
Copy code
expect class PeopleInSpaceDatabaseWrapper {
    fun database() : PeopleInSpaceDatabase?
}
and then for example in androidMain
Copy code
@Single
actual class PeopleInSpaceDatabaseWrapper(val context: Context) {
    actual fun database(): PeopleInSpaceDatabase?
        = PeopleInSpaceDatabase(AndroidSqliteDriver(PeopleInSpaceDatabase.Schema, context, "peopleinspace.db"))
}
a
it's updated on your branch?
j
Yeah
a
ok I will update my local branch
for now you could use
@Provided
:
this will skip the check for PeopleInSpaceDatabaseWrapper
but else, yes, it should relay a bit more on expect + annotation to confirm locally that this dependency will be provided in native sources
You have also several modules scanning on the same package
@ComponentScan
can scan across modules
j
ah, ok.....I'll give that a go later
πŸ‘ 1
am also very open to changing around how
PeopleInSpaceDatabaseWrapper
is wired up etc if you think there might be better way
it was created primarily to address there not being a driver for JS
(so null passed to it in JS case and then checked in repository)
a
sure, I'll look again
j
so, is that
@Provided
something that will generally be needed in this case or just workaround for now?
a
it's declare a dependency as "provided" later, we ensure that the type is safe on our own
j
I tried adding that
@Provided
(and also removed the unncessary
@ComponentScan
s)....it's building now but getting following crash at runtime
Copy code
11-19 16:35:33.747 15979 15979 E [Koin]  : * Instance creation error : could not create instance for '[Singleton: 'com.surrus.common.repository.PeopleInSpaceRepository',binds:com.surrus.common.repository.PeopleInSpaceRepositoryInterface]': org.koin.core.error.NoDefinitionFoundException: No definition found for type 'com.surrus.common.di.PeopleInSpaceDatabaseWrapper'. Check your Modules configuration and add missing type and/or qualifier!
a
I've done something dirty also ^^
not best for now
image.png
this works, but nullable requires your wrapper then.
I will need a bit more time on this ^^
j
yeah, I think I tried something like that but ran in to issues with it being nullable
but the above worked ok for you? (I might have done something wrong when I tried it)
it would be nice not to have to need that wrapper
πŸ‘ 1
a
yes could be better o avoid this wrapper
finally, the annotation stuff is more tricky than I was expected πŸ˜…
πŸ˜… 1
k
@John O'Reilly were you able to run your project successfully? experiencing a similar issue on my project.
j
Not quite yet....will take another look at the weekend
πŸ†— 1
a
We should need a last update I guess
j
@arnaud.giuliani just to confirm, do you think this should be possible right now or will we need a koin update?
a
we can hack in the ay I was showing. I would like to adjust that, but it can be a 2nd step
j
that's using the
peopleInSpaceDatabase()
single? I thought there was issue if that was nullable....
a
and then we need a wrapper for that
j
trying that now but running in to issue for say Android version where I need to provide context
Copy code
@Single
    actual fun getPeopleInSpaceDatabaseWrapper(context: Context)
        = PeopleInSpaceDatabaseWrapper(PeopleInSpaceDatabase(AndroidSqliteDriver(PeopleInSpaceDatabase.Schema, context, "peopleinspace.db")))
where I have following in commonMain
Copy code
@Module
expect class NativeModule() {
    @Single
    fun getHttpClientEngine(): HttpClientEngine

    @Single
    fun getPeopleInSpaceDatabaseWrapper(): PeopleInSpaceDatabaseWrapper
}
a
to provide context I've cheated using KoinComponent on the given module
j
where did you add that?
a
on your NativeModule class, to let your resolve the Android Context instance with getKoin().get()