From 7df9e169dcdaabee4b806f14a3db737eeca64cc4 Mon Sep 17 00:00:00 2001 From: Arnaud Giuliani Date: Fri, 30 Aug 2024 14:59:20 +0200 Subject: [PATCH] doc update - Compose --- docs/reference/koin-compose/compose.md | 107 +++++-- .../koin-compose/isolated-context.md | 2 +- docs/reference/koin-compose/multiplatform.md | 113 -------- .../docs/quickstart/android-annotations.md | 269 ------------------ projects/docs/quickstart/android-compose.md | 245 ---------------- projects/docs/quickstart/android-viewmodel.md | 207 -------------- projects/docs/quickstart/android.md | 207 -------------- projects/docs/quickstart/junit-test.md | 93 ------ projects/docs/quickstart/kmp.md | 204 ------------- .../docs/quickstart/kotlin-annotations.md | 182 ------------ projects/docs/quickstart/kotlin.md | 165 ----------- projects/docs/quickstart/ktor.md | 184 ------------ projects/docs/resources/articles.md | 22 -- projects/docs/resources/index.md | 18 -- projects/docs/resources/videos.md | 12 - projects/docs/setup/koin.md | 224 --------------- projects/docs/setup/why.md | 132 --------- projects/docs/support/index.md | 42 --- projects/docs/upgrade/migrate.md | 73 ----- projects/docs/upgrade/whats-new.md | 9 - 20 files changed, 84 insertions(+), 2426 deletions(-) delete mode 100644 docs/reference/koin-compose/multiplatform.md delete mode 100755 projects/docs/quickstart/android-annotations.md delete mode 100755 projects/docs/quickstart/android-compose.md delete mode 100755 projects/docs/quickstart/android-viewmodel.md delete mode 100755 projects/docs/quickstart/android.md delete mode 100644 projects/docs/quickstart/junit-test.md delete mode 100755 projects/docs/quickstart/kmp.md delete mode 100755 projects/docs/quickstart/kotlin-annotations.md delete mode 100755 projects/docs/quickstart/kotlin.md delete mode 100755 projects/docs/quickstart/ktor.md delete mode 100644 projects/docs/resources/articles.md delete mode 100644 projects/docs/resources/index.md delete mode 100644 projects/docs/resources/videos.md delete mode 100644 projects/docs/setup/koin.md delete mode 100644 projects/docs/setup/why.md delete mode 100644 projects/docs/support/index.md delete mode 100644 projects/docs/upgrade/migrate.md delete mode 100644 projects/docs/upgrade/whats-new.md diff --git a/docs/reference/koin-compose/compose.md b/docs/reference/koin-compose/compose.md index 68d6aa22f..a69602c3f 100644 --- a/docs/reference/koin-compose/compose.md +++ b/docs/reference/koin-compose/compose.md @@ -1,50 +1,83 @@ --- -title: Injecting in Jetpack Compose and Android +title: Koin for Jetpack Compose and Compose Multiplatform --- -This page describe how you can inject your dependencies for your Jetpack Compose app - https://developer.android.com/jetpack/compose +This page describe how you can inject your dependencies for your [Android Jetpack Compose](https://developer.android.com/jetpack/compose) or your [Multiplaform Compose](https://www.jetbrains.com/lp/compose-mpp/) apps. -## Starting Koin with Android Jetpack Compose - KoinApplication or KoinAndroidContext -Most of the time, `startKoin` function is used to start Koin in your application. This is done before running any Composable function. You need to setting up Compose with your current Koin instance. Use `KoinAndroidContext()` to do so: +## Koin Compose Multiplatform vs Koin Android Jetpack Compose + +Since mid 2024, Compose applications can be done with Koin Multiplatform API. All APIs are identifcal between Koin Jetpack Compose (koin-androidx-compose) and Koin Compose Multiplatform (koin-compose). + +### What Koin package for Compose? + +for a pure Android app that uses only Android Jetpack Compose API, use the following packages: +- `koin-androidx-compose` - to unlock Compose base API + Compose ViewModel API +- `koin-androidx-compose-navigation` - Compose ViewModel API with Navigation API integration + +for an Android/Multiplatform app, use the following packages: +- `koin-compose` - Compose base API +- `koin-compose-viewmodel` - Compose ViewModel API +- `koin-compose-viewmodel-navigation` - Compose ViewModel API with Navigation API integration + +## Starting Koin in a Compose App with KoinApplication + +The function `KoinApplication` helps to create Koin application instance, as a Composable: ```kotlin +fun koinConfiguration() = koinApplication { + // your configuration & modules here + modules(...) +} + @Composable fun App() { - // Set current Koin instance to Compose context - KoinAndroidContext() { - + KoinApplication(::koinConfiguration) { + + // your screens here ... MyScreen() } } ``` -Else if you want to start a new Koin instance from your Compose app, The function `KoinApplication` helps to create Koin application instance, as a Composable. This is a replacement of the classic `startKoin` application function. +The `KoinApplication` function will handle start & stop of your Koin context, regarding the cycle of the Compose context. This function start and stop a new Koin application context. + +:::info +In an Android Application, the `KoinApplication` will handle any need to stop/restart Koin context regarding configuration changes or drop of Activities. +::: + +:::note +This replaces the use of the classic `startKoin` application function. +::: + +## Starting over an existing Koin context + +Some time the `startKoin` function is already used in the application, to start Koin in your application (like in Android main app class, the Application class). In that case you need to inform your Compose application about the current Koin context with `KoinContext` or `KoinAndroidContext`. Those functions reuse current Koin context and bind it to the Compose application. ```kotlin @Composable fun App() { - KoinApplication(application = { - // Koin configuration here - }) { - + // Set current Koin instance to Compose context + KoinContext() { + + MyScreen() } } ``` -:::note +:::info Difference between `KoinAndroidContext` and `KoinContext`: - `KoinAndroidContext` is looking into current Android app context for Koin instance - `KoinContext` is looking into current GlobalContext for Koin instances ::: -:::info +:::note If you get some `ClosedScopeException` from a Composable, either use `KoinContext` on your Composable or ensure to have proper Koin start configuration [with Android context](/docs/reference/koin-android/start.md#from-your-application-class) ::: ### Compose Preview with Koin -The `KoinApplication` function is also interesting to start dedicated context for preview. This can be also used to help with Compose preview: +The `KoinApplication` function is interesting to start dedicated context for preview. This can be also used to help with Compose preview: ```kotlin @Composable @@ -61,10 +94,7 @@ fun App() { ## Injecting into a @Composable -While writing your composable function, you gain access to the following Koin API: - -* `koinInject()` - fetch instance from Koin container -* `getKoin()` - get current Koin instance +While writing your composable function, you gain access to the following Koin API: `koinInject()`, to inject instance from Koin container For a module that declares a 'MyService' component: @@ -85,13 +115,13 @@ fun App() { } ``` -:::note -To keep aligned on the functional aspect of Jetpack Compose, the best writing approach is to inject instances directly into functions properties. This way allow to have default implementation with Koin, but keep open to inject instances how you want. -::: + +To keep aligned on the functional aspect of Jetpack Compose, the best writing approach is to inject instances directly into functions parameters. This way allow to have default implementation with Koin, but keep open to inject instances how you want. ```kotlin @Composable fun App(myService: MyService = koinInject()) { + } ``` @@ -99,7 +129,8 @@ fun App(myService: MyService = koinInject()) { The same way you have access to classical single/factory instances, you gain access to the following Koin ViewModel API: -* `koinViewModel()` - fetch instance +* `koinViewModel()` - inject ViewModel instance +* `koinNavViewModel()` - inject ViewModel instance + Navigation arguments data (if you are using `Navigation` API) For a module that declares a 'MyViewModel' component: @@ -130,6 +161,34 @@ fun App(vm : MyViewModel = koinViewModel()) { ``` :::warning -Lazy API is not supported with updates of jetpack Compose 1.1+ +Lazy API are not supported with updates of jetpack Compose ::: + + +## Module loading & unloading tied to Composable + +Koin offers you a way to load specific modules for a given Composable function. The `rememberKoinModules` function load Koin modules and remember on current Composable: + +```kotlin +@Composable +@Preview +fun MyComponentComposable() { + // load module at first call of this component + rememberKoinModules(myModule) +} +``` + +You can use one of the abandon function, to unload module on 2 aspects: +- onForgotten - after a composition is dropped out +- onAbandoned - composition has failed + +For this use `unloadOnForgotten` or `unloadOnAbandoned` argument for `rememberKoinModules`. + +## Creating Koin Scope with Composable + +The composable function `rememberKoinScope` and `KoinScope` allow to handle Koin Scope in a Composable, follow-up current to close scope once Composable is ended. + +:::info +this API is still unstable for now +::: \ No newline at end of file diff --git a/docs/reference/koin-compose/isolated-context.md b/docs/reference/koin-compose/isolated-context.md index a2a18a6d2..731209a12 100644 --- a/docs/reference/koin-compose/isolated-context.md +++ b/docs/reference/koin-compose/isolated-context.md @@ -1,5 +1,5 @@ --- -title: Isolated Context with Compose +title: Isolated Context with Compose Applications --- With a Compose application, you can work the same way with an [isolated context](/docs/reference/koin-core/context-isolation.md) to deal with SDK or white label application, in order to not mix your Koin definitions with an end user's one. diff --git a/docs/reference/koin-compose/multiplatform.md b/docs/reference/koin-compose/multiplatform.md deleted file mode 100644 index 1ae5a0ebb..000000000 --- a/docs/reference/koin-compose/multiplatform.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Compose Multiplatform Features ---- - -This page describe how you can inject your dependencies for your Jetpack & Jetbrains Compose app - https://www.jetbrains.com/lp/compose-mpp/ - -## Starting Koin with Compose - KoinApplication or KoinContext - -Most of the time, `startKoin` function is used to start Koin in your application. This is done before running any Composable function. You need to seting up Compose with your current Koin instance. Use `KoinContext()` to do so: - -```kotlin -@Composable -fun App() { - // Set current Koin instance to Compose context - KoinContext() { - - MyScreen() - } -} -``` - -Else if you want to start a new Koin instance from your Compose app, The function `KoinApplication` helps to create Koin application instance, as a Composable. This is a replacement of the classic `startKoin` application function. - -```kotlin -@Composable -fun App() { - KoinApplication(application = { - // Koin configuration here - }) { - - } -} -``` - -### Compose Preview with Koin - -The `KoinApplication` function is also interesting to start dedicated context for preview. This can be also used to help with Compose preview: - -```kotlin -@Composable -@Preview -fun App() { - KoinApplication(application = { - // your preview config here - modules(previewModule) - }) { - // Compose to preview with Koin - } -} -``` - -## Injecting into a @Composable - -While writing your composable function, you gain access to the following Koin API: - -* `koinInject()` - fetch instance from Koin container -* `getKoin()` - get current Koin instance - -For a module that declares a 'MyService' component: - -```kotlin -val androidModule = module { - - single { MyService() } -} -``` - -We can get your instance like that: - -```kotlin -@Composable -fun App() { - val myService = koinInject() -} -``` - -:::note -To keep aligned on the functional aspect of Jetpack Compose, the best writing approach is to inject instances directly into functions properties. This way allow to have default implementation with Koin, but keep open to inject instances how you want. -::: - -```kotlin -@Composable -fun App(myService: MyService = koinInject()) { -} -``` - - -## Module loading & unloading tied to Composable - -Koin offers you a way to load specific modules for a given Composable function. The `rememberKoinModules` function load Koin modules and remember on current Composable: - -```kotlin -@Composable -@Preview -fun MyComponentComposable() { - // load module at first call of this component - rememberKoinModules { listOf(myModule) } -} -``` - -You can use one of the abandon function, to unload module on 2 aspects: -- onForgotten - after a composition is dropped out -- onAbandoned - composition has failed - -For this use `unloadOnForgotten` or `unloadOnAbandoned` argument for `rememberKoinModules`. - -## Creating Koin Scope with Composable - -The composable function `rememberKoinScope` and `KoinScope` allow to handle Koin Scope in a Composable, follow-up current to close scope once Composable is ended. - -:::info -this API is still unstable for now -::: diff --git a/projects/docs/quickstart/android-annotations.md b/projects/docs/quickstart/android-annotations.md deleted file mode 100755 index d4b07c2a8..000000000 --- a/projects/docs/quickstart/android-annotations.md +++ /dev/null @@ -1,269 +0,0 @@ ---- -title: Android - Annotations ---- - -> This tutorial lets you write an Android application and use Koin dependency injection to retrieve your components. -> You need around __10/15 min__ to do the tutorial. - -## Get the code - -:::info -[The source code is available at on Github](https://github.com/InsertKoinIO/koin-getting-started/tree/main/android) -::: - -## Gradle Setup - -Let's configure the KSP Plugin like this: - -```groovy -apply plugin: 'com.google.devtools.ksp' - -android { - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - test.java.srcDirs += 'src/test/kotlin' - } - // For KSP - applicationVariants.configureEach { variant -> - kotlin.sourceSets { - getByName(name) { - kotlin.srcDir("build/generated/ksp/${variant.name}/kotlin") - } - } - } -} -``` - -Add the Koin Android dependency like below: - -```groovy -dependencies { - // Koin - implementation "io.insert-koin:koin-android:$koin_version" - implementation "io.insert-koin:koin-annotations:$koin_ksp_version" - ksp "io.insert-koin:koin-ksp-compiler:$koin_ksp_version" -} -``` - - - -## Application Overview - -The idea of the application is to manage a list of users, and display it in our `MainActivity` class with a Presenter or a ViewModel: - -> Users -> UserRepository -> (Presenter or ViewModel) -> MainActivity - -## The "User" Data - -We will manage a collection of Users. Here is the data class: - -```kotlin -data class User(val name : String) -``` - -We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the `UserRepository` interface and its implementation: - -```kotlin -interface UserRepository { - fun findUser(name : String): User? - fun addUsers(users : List) -} - -class UserRepositoryImpl : UserRepository { - - private val _users = arrayListOf() - - override fun findUser(name: String): User? { - return _users.firstOrNull { it.name == name } - } - - override fun addUsers(users : List) { - _users.addAll(users) - } -} -``` - -## The Koin module - -Let's declare a `AppModule` module class like below. - -```kotlin -@Module -@ComponentScan("org.koin.sample") -class AppModule -``` - -* We use the `@Module` to declare our class as Koin module -* The `@ComponentScan("org.koin.sample")` allow to scann any Koin definition in `"org.koin.sample"`package - -Let's simply add `@Single` on `UserRepositoryImpl` class to declare it as singleton: - -```kotlin -@Single -class UserRepositoryImpl : UserRepository { - // ... -} -``` - -## Displaying User with Presenter - -Let's write a presenter component to display a user: - -```kotlin -class UserPresenter(private val repository: UserRepository) { - - fun sayHello(name : String) : String{ - val foundUser = repository.findUser(name) - return foundUser?.let { "Hello '$it' from $this" } ?: "User '$name' not found!" - } -} -``` - -> UserRepository is referenced in UserPresenter`s constructor - -We declare `UserPresenter` in our Koin module. We declare it as a `factory` definition with the `@Factory` annotation, to not keep any instance in memory (avoid any leak with Android lifecycle): - -```kotlin -@Factory -class UserPresenter(private val repository: UserRepository) { - // ... -} -``` - -## Injecting Dependencies in Android - -The `UserPresenter` component will be created, resolving the `UserRepository` instance with it. To get it into our Activity, let's inject it with the `by inject()` delegate function: - -```kotlin -class MainActivity : AppCompatActivity() { - - private val presenter: UserPresenter by inject() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - //... - } -} -``` - -That's it, your app is ready. - -:::info -The `by inject()` function allows us to retrieve Koin instances, in Android components runtime (Activity, fragment, Service...) -::: - -## Start Koin - -We need to start Koin with our Android application. Just call the `startKoin()` function in the application's main entry point, our `MainApplication` class: - -```kotlin -// generated -import org.koin.ksp.generated.* - -class MainApplication : Application(){ - override fun onCreate() { - super.onCreate() - - startKoin{ - androidLogger() - androidContext(this@MainApplication) - modules(AppModule().module) - } - } -} -``` - -The Koin module is generated from `AppModule` with the `.module` extension: Just use the `AppModule().module` expression to get the Koin module from the annotations. - -:::info -The `import org.koin.ksp.generated.*` import is required to allow to use generated Koin module content -::: - -## Displaying User with ViewModel - -Let's write a ViewModel component to display a user: - -```kotlin -@KoinViewModel -class UserViewModel(private val repository: UserRepository) : ViewModel() { - - fun sayHello(name : String) : String{ - val foundUser = repository.findUser(name) - return foundUser?.let { "Hello '$it' from $this" } ?: "User '$name' not found!" - } -} -``` - -> UserRepository is referenced in UserViewModel`s constructor - -The `UserViewModel` is tagged with `@KoinViewModel` annotation to declare the Koin ViewModel definition, to not keep any instance in memory (avoid any leak with Android lifecycle). - - -## Injecting ViewModel in Android - -The `UserViewModel` component will be created, resolving the `UserRepository` instance with it. To get it into our Activity, let's inject it with the `by viewModel()` delegate function: - -```kotlin -class MainActivity : AppCompatActivity() { - - private val viewModel: UserViewModel by viewModel() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - //... - } -} -``` - -## Compile Time Checks - -Koin Annotations allows to check your Koin configuration at compile time. This is available by jusing the following Gradle option: - -```groovy -ksp { - arg("KOIN_CONFIG_CHECK","true") -} -``` - -## Verifying your App! - -We can ensure that our Koin configuration is good before launching our app, by verifying our Koin configuration with a simple JUnit Test. - -### Gradle Setup - -Add the Koin Android dependency like below: - -```groovy -// Add Maven Central to your repositories if needed -repositories { - mavenCentral() -} - -dependencies { - - // Koin for Tests - testImplementation "io.insert-koin:koin-test-junit4:$koin_version" -} -``` - -### Checking your modules - -The `verify()` function allow to verify the given Koin modules: - -```kotlin -class CheckModulesTest : KoinTest { - - @Test - fun checkAllModules() { - - AppModule().module.verify( - extraTypes = listOf( - SavedStateHandle::class - )) - } -} -``` - -With just a JUnit test, you can ensure your definitions configuration are not missing anything! diff --git a/projects/docs/quickstart/android-compose.md b/projects/docs/quickstart/android-compose.md deleted file mode 100755 index b1977f3c3..000000000 --- a/projects/docs/quickstart/android-compose.md +++ /dev/null @@ -1,245 +0,0 @@ ---- -title: Android - Jetpack Compose ---- - -> This tutorial lets you write an Android application and use Koin dependency injection to retrieve your components. -> You need around __10 min__ to do the tutorial. - -## Get the code - -:::info -[The source code is available at on Github](https://github.com/InsertKoinIO/koin-getting-started/tree/main/android-compose) -::: - -## Gradle Setup - -Add the Koin Android dependency like below: - -```groovy -dependencies { - - // Koin for Android - implementation "io.insert-koin:koin-androidx-compose:$koin_version" -} -``` - -## Application Overview - -The idea of the application is to manage a list of users, and display it in our `MainActivity` class with a Presenter or a ViewModel: - -> Users -> UserRepository -> (Presenter or ViewModel) -> Composable - -## The "User" Data - -We will manage a collection of Users. Here is the data class: - -```kotlin -data class User(val name : String) -``` - -We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the `UserRepository` interface and its implementation: - -```kotlin -interface UserRepository { - fun findUser(name : String): User? - fun addUsers(users : List) -} - -class UserRepositoryImpl : UserRepository { - - private val _users = arrayListOf() - - override fun findUser(name: String): User? { - return _users.firstOrNull { it.name == name } - } - - override fun addUsers(users : List) { - _users.addAll(users) - } -} -``` - -## The Koin module - -Use the `module` function to declare a Koin module. A Koin module is the place where we define all our components to be injected. - -```kotlin -val appModule = module { - -} -``` - -Let's declare our first component. We want a singleton of `UserRepository`, by creating an instance of `UserRepositoryImpl` - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } -} -``` - -## Displaying User with UserViewModel - -### The `UserViewModel` class - -Let's write a ViewModel component to display a user: - -```kotlin -class UserViewModel(private val repository: UserRepository) : ViewModel() { - - fun sayHello(name : String) : String{ - val foundUser = repository.findUser(name) - return foundUser?.let { "Hello '$it' from $this" } ?: "User '$name' not found!" - } -} -``` - -> UserRepository is referenced in UserViewModel's constructor - -We declare `UserViewModel` in our Koin module. We declare it as a `viewModel` definition, to not keep any instance in memory (avoid any leak with Android lifecycle): - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } - viewModel { MyViewModel(get()) } -} -``` - -> The `get()` function allow to ask Koin to resolve the needed dependency. - -### Injecting ViewModel in Compose - -The `UserViewModel` component will be created, resolving the `UserRepository` instance with it. To get it into our Activity, let's inject it with the `koinViewModel()` function: - -```kotlin -@Composable -fun ViewModelInject(userName : String, viewModel: UserViewModel = koinViewModel()){ - Text(text = viewModel.sayHello(userName), modifier = Modifier.padding(8.dp)) -} -``` - -:::info -The `koinViewModel` function allows us to retrieve a ViewModel instances, create the associated ViewModel Factory for you and bind it to the lifecycle -::: - -## Displaying User with UserStateHolder - -### The `UserStateHolder` class - -Let's write a State holder component to display a user: - -```kotlin -class UserStateHolder(private val repository: UserRepository) { - - fun sayHello(name : String) : String{ - val foundUser = repository.findUser(name) - return foundUser?.let { "Hello '$it' from $this" } ?: "User '$name' not found!" - } -} -``` - -> UserRepository is referenced in UserViewModel's constructor - -We declare `UserStateHolder` in our Koin module. We declare it as a `factory` definition, to not keep any instance in memory (avoid any leak with Android lifecycle): - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } - factory { UserStateHolder(get()) } -} -``` - -### Injecting UserStateHolder in Compose - -The `UserStateHolder` component will be created, resolving the `UserRepository` instance with it. To get it into our Activity, let's inject it with the `koinInject()` function: - -```kotlin -@Composable -fun FactoryInject(userName : String, presenter: UserStateHolder = koinInject()){ - Text(text = presenter.sayHello(userName), modifier = Modifier.padding(8.dp)) -} -``` - -:::info -The `koinInject` function allows us to retrieve a ViewModel instances, create the associated ViewModel Factory for you and bind it to the lifecycle -::: - - -## Start Koin - -We need to start Koin with our Android application. Just call the `startKoin()` function in the application's main entry point, our `MainApplication` class: - -```kotlin -class MainApplication : Application(){ - override fun onCreate() { - super.onCreate() - - startKoin{ - androidLogger() - androidContext(this@MainApplication) - modules(appModule) - } - } -} -``` - -:::info -The `modules()` function in `startKoin` load the given list of modules -::: - -## Koin module: classic or constructor DSL? - -Here is the Koin moduel declaration for our app: - -```kotlin -val appModule = module { - single { HelloRepositoryImpl() } - viewModel { MyViewModel(get()) } -} -``` - -We can write it in a more compact way, by using constructors: - -```kotlin -val appModule = module { - singleOf(::UserRepositoryImpl) { bind() } - viewModelOf(::UserViewModel) -} -``` - -## Verifying your App! - -We can ensure that our Koin configuration is good before launching our app, by verifying our Koin configuration with a simple JUnit Test. - -### Gradle Setup - -Add the Koin Android dependency like below: - -```groovy -// Add Maven Central to your repositories if needed -repositories { - mavenCentral() -} - -dependencies { - - // Koin for Tests - testImplementation "io.insert-koin:koin-test-junit4:$koin_version" -} -``` - -### Checking your modules - -The `verify()` function allow to verify the given Koin modules: - -```kotlin -class CheckModulesTest : KoinTest { - - @Test - fun checkAllModules() { - appModule.verify() - } -} -``` - -With just a JUnit test, you can ensure your definitions configuration are not missing anything! - diff --git a/projects/docs/quickstart/android-viewmodel.md b/projects/docs/quickstart/android-viewmodel.md deleted file mode 100755 index 5f6b5d52a..000000000 --- a/projects/docs/quickstart/android-viewmodel.md +++ /dev/null @@ -1,207 +0,0 @@ ---- -title: Android - ViewModel ---- - -> This tutorial lets you write an Android application and use Koin dependency injection to retrieve your components. -> You need around __10/15 min__ to do the tutorial. - -## Get the code - -:::info -[The source code is available at on Github](https://github.com/InsertKoinIO/koin-getting-started/tree/main/android) -::: - -## Gradle Setup - -Add the Koin Android dependency like below: - -```groovy -dependencies { - - // Koin for Android - implementation "io.insert-koin:koin-android:$koin_version" -} -``` - -## Application Overview - -The idea of the application is to manage a list of users, and display it in our `MainActivity` class with a Presenter or a ViewModel: - -> Users -> UserRepository -> (Presenter or ViewModel) -> MainActivity - -## The "User" Data - -We will manage a collection of Users. Here is the data class: - -```kotlin -data class User(val name : String) -``` - -We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the `UserRepository` interface and its implementation: - -```kotlin -interface UserRepository { - fun findUser(name : String): User? - fun addUsers(users : List) -} - -class UserRepositoryImpl : UserRepository { - - private val _users = arrayListOf() - - override fun findUser(name: String): User? { - return _users.firstOrNull { it.name == name } - } - - override fun addUsers(users : List) { - _users.addAll(users) - } -} -``` - -## The Koin module - -Use the `module` function to declare a Koin module. A Koin module is the place where we define all our components to be injected. - -```kotlin -val appModule = module { - -} -``` - -Let's declare our first component. We want a singleton of `UserRepository`, by creating an instance of `UserRepositoryImpl` - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } -} -``` - -## Displaying User with ViewModel - -Let's write a ViewModel component to display a user: - -```kotlin -class UserViewModel(private val repository: UserRepository) : ViewModel() { - - fun sayHello(name : String) : String{ - val foundUser = repository.findUser(name) - return foundUser?.let { "Hello '$it' from $this" } ?: "User '$name' not found!" - } -} -``` - -> UserRepository is referenced in UserViewModel`s constructor - -We declare `UserViewModel` in our Koin module. We declare it as a `viewModel` definition, to not keep any instance in memory (avoid any leak with Android lifecycle): - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } - viewModel { MyViewModel(get()) } -} -``` - -> The `get()` function allow to ask Koin to resolve the needed dependency. - -## Injecting ViewModel in Android - -The `UserViewModel` component will be created, resolving the `UserRepository` instance with it. To get it into our Activity, let's inject it with the `by viewModel()` delegate function: - -```kotlin -class MainActivity : AppCompatActivity() { - - private val viewModel: UserViewModel by viewModel() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - //... - } -} -``` - -That's it, your app is ready. - -:::info -The `by viewModel()` function allows us to retrieve a ViewModel instances, create the associated ViewModel Factory for you and bind it to the lifecycle -::: - -## Start Koin - -We need to start Koin with our Android application. Just call the `startKoin()` function in the application's main entry point, our `MainApplication` class: - -```kotlin -class MainApplication : Application(){ - override fun onCreate() { - super.onCreate() - - startKoin{ - androidLogger() - androidContext(this@MainApplication) - modules(appModule) - } - } -} -``` - -:::info -The `modules()` function in `startKoin` load the given list of modules -::: - -## Koin module: classic or constructor DSL? - -Here is the Koin moduel declaration for our app: - -```kotlin -val appModule = module { - single { HelloRepositoryImpl() } - viewModel { MyViewModel(get()) } -} -``` - -We can write it in a more compact way, by using constructors: - -```kotlin -val appModule = module { - singleOf(::UserRepositoryImpl) { bind() } - viewModelOf(::UserViewModel) -} -``` - -## Verifying your App! - -We can ensure that our Koin configuration is good before launching our app, by verifying our Koin configuration with a simple JUnit Test. - -### Gradle Setup - -Add the Koin Android dependency like below: - -```groovy -// Add Maven Central to your repositories if needed -repositories { - mavenCentral() -} - -dependencies { - - // Koin for Tests - testImplementation "io.insert-koin:koin-test-junit4:$koin_version" -} -``` - -### Checking your modules - -The `verify()` function allow to verify the given Koin modules: - -```kotlin -class CheckModulesTest : KoinTest { - - @Test - fun checkAllModules() { - appModule.verify() - } -} -``` - -With just a JUnit test, you can ensure your definitions configuration are not missing anything! diff --git a/projects/docs/quickstart/android.md b/projects/docs/quickstart/android.md deleted file mode 100755 index 96d21e02f..000000000 --- a/projects/docs/quickstart/android.md +++ /dev/null @@ -1,207 +0,0 @@ ---- -title: Android ---- - -> This tutorial lets you write an Android application and use Koin dependency injection to retrieve your components. -> You need around __10/15 min__ to do the tutorial. - -## Get the code - -:::info -[The source code is available at on Github](https://github.com/InsertKoinIO/koin-getting-started/tree/main/android) -::: - -## Gradle Setup - -Add the Koin Android dependency like below: - -```groovy -dependencies { - - // Koin for Android - implementation "io.insert-koin:koin-android:$koin_version" -} -``` - -## Application Overview - -The idea of the application is to manage a list of users, and display it in our `MainActivity` class with a Presenter or a ViewModel: - -> Users -> UserRepository -> (Presenter or ViewModel) -> MainActivity - -## The "User" Data - -We will manage a collection of Users. Here is the data class: - -```kotlin -data class User(val name : String) -``` - -We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the `UserRepository` interface and its implementation: - -```kotlin -interface UserRepository { - fun findUser(name : String): User? - fun addUsers(users : List) -} - -class UserRepositoryImpl : UserRepository { - - private val _users = arrayListOf() - - override fun findUser(name: String): User? { - return _users.firstOrNull { it.name == name } - } - - override fun addUsers(users : List) { - _users.addAll(users) - } -} -``` - -## The Koin module - -Use the `module` function to declare a Koin module. A Koin module is the place where we define all our components to be injected. - -```kotlin -val appModule = module { - -} -``` - -Let's declare our first component. We want a singleton of `UserRepository`, by creating an instance of `UserRepositoryImpl` - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } -} -``` - -## Displaying User with Presenter - -Let's write a presenter component to display a user: - -```kotlin -class UserPresenter(private val repository: UserRepository) { - - fun sayHello(name : String) : String{ - val foundUser = repository.findUser(name) - return foundUser?.let { "Hello '$it' from $this" } ?: "User '$name' not found!" - } -} -``` - -> UserRepository is referenced in UserPresenter`s constructor - -We declare `UserPresenter` in our Koin module. We declare it as a `factory` definition, to not keep any instance in memory (avoid any leak with Android lifecycle): - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } - factory { MyPresenter(get()) } -} -``` - -> The `get()` function allow to ask Koin to resolve the needed dependency. - -## Injecting Dependencies in Android - -The `UserPresenter` component will be created, resolving the `UserRepository` instance with it. To get it into our Activity, let's inject it with the `by inject()` delegate function: - -```kotlin -class MainActivity : AppCompatActivity() { - - private val presenter: UserPresenter by inject() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - //... - } -} -``` - -That's it, your app is ready. - -:::info -The `by inject()` function allows us to retrieve Koin instances, in Android components runtime (Activity, fragment, Service...) -::: - -## Start Koin - -We need to start Koin with our Android application. Just call the `startKoin()` function in the application's main entry point, our `MainApplication` class: - -```kotlin -class MainApplication : Application(){ - override fun onCreate() { - super.onCreate() - - startKoin{ - androidLogger() - androidContext(this@MainApplication) - modules(appModule) - } - } -} -``` - -:::info -The `modules()` function in `startKoin` load the given list of modules -::: - -## Koin module: classic or constructor DSL? - -Here is the Koin moduel declaration for our app: - -```kotlin -val appModule = module { - single { HelloRepositoryImpl() } - factory { MyPresenter(get()) } -} -``` - -We can write it in a more compact way, by using constructors: - -```kotlin -val appModule = module { - singleOf(::UserRepositoryImpl) { bind() } - factoryOf(::UserPresenter) -} -``` - -## Verifying your App! - -We can ensure that our Koin configuration is good before launching our app, by verifying our Koin configuration with a simple JUnit Test. - -### Gradle Setup - -Add the Koin Android dependency like below: - -```groovy -// Add Maven Central to your repositories if needed -repositories { - mavenCentral() -} - -dependencies { - - // Koin for Tests - testImplementation "io.insert-koin:koin-test-junit4:$koin_version" -} -``` - -### Checking your modules - -The `verify()` function allow to verify the given Koin modules: - -```kotlin -class CheckModulesTest : KoinTest { - - @Test - fun checkAllModules() { - appModule.verify() - } -} -``` - -With just a JUnit test, you can ensure your definitions configuration are not missing anything! diff --git a/projects/docs/quickstart/junit-test.md b/projects/docs/quickstart/junit-test.md deleted file mode 100644 index a440648a1..000000000 --- a/projects/docs/quickstart/junit-test.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: JUnit Tests ---- - -> This tutorial lets you test a Kotlin application and use Koin inject and retrieve your components. - -## Get the code - -:::info -[The source code is available at on Github](https://github.com/InsertKoinIO/koin-getting-started/tree/main/kotlin) -::: - -## Gradle Setup - -First, add the Koin dependency like below: - -```groovy -dependencies { - // Koin testing tools - testCompile "io.insert-koin:koin-test:$koin_version" - // Needed JUnit version - testCompile "io.insert-koin:koin-test-junit4:$koin_version" -} -``` - -## Declared dependencies - -We reuse the `koin-core` getting-started project, to use the koin module: - -```kotlin -val helloModule = module { - single { HelloMessageData() } - single { HelloServiceImpl(get()) as HelloService } -} -``` - -## Writing our first Test - -To make our first test, let's write a simple Junit test file and extend it with `KoinTest`. We will be able then, to use `by inject()` operators. - -```kotlin -class HelloAppTest : KoinTest { - - val model by inject() - val service by inject() - - @get:Rule - val koinTestRule = KoinTestRule.create { - printLogger() - modules(helloModule) - } - - @Test - fun `unit test`() { - val helloApp = HelloApplication() - helloApp.sayHello() - - assertEquals(service, helloApp.helloService) - assertEquals("Hey, ${model.message}", service.hello()) - } -} -``` - -> We use the Koin KoinTestRule rule to start/stop our Koin context - -You can even make Mocks directly into MyPresenter, or test MyRepository. Those components doesn't have any link with Koin API. - -```kotlin -class HelloMockTest : KoinTest { - - @get:Rule - val koinTestRule = KoinTestRule.create { - printLogger(Level.DEBUG) - modules(helloModule) - } - - @get:Rule - val mockProvider = MockProviderRule.create { clazz -> - Mockito.mock(clazz.java) - } - - @Test - fun `mock test`() { - val service = declareMock { - given(hello()).willReturn("Hello Mock") - } - - HelloApplication().sayHello() - - Mockito.verify(service,times(1)).hello() - } -} -``` diff --git a/projects/docs/quickstart/kmp.md b/projects/docs/quickstart/kmp.md deleted file mode 100755 index 764edbebf..000000000 --- a/projects/docs/quickstart/kmp.md +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: Kotlin Multiplatform - Mobile Apps ---- - -> This tutorial lets you write an Android application and use Koin dependency injection to retrieve your components. -> You need around __10/15 min__ to do the tutorial. - -## Get the code - -:::info -[The source code is available at on Github](https://github.com/InsertKoinIO/koin-getting-started/tree/main/kmp) -::: - -## Application Overview - -The idea of the application is to manage a list of users, and display it in our native UI, witha shared Presenter: - -`Users -> UserRepository -> Shared Presenter -> Native UI` - -## The "User" Data - -> All the common/shared code is located in `shared` Gradle project - -We will manage a collection of Users. Here is the data class: - -```kotlin -data class User(val name : String) -``` - -We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the `UserRepository` interface and its implementation: - -```kotlin -interface UserRepository { - fun findUser(name : String): User? - fun addUsers(users : List) -} - -class UserRepositoryImpl : UserRepository { - - private val _users = arrayListOf() - - override fun findUser(name: String): User? { - return _users.firstOrNull { it.name == name } - } - - override fun addUsers(users : List) { - _users.addAll(users) - } -} -``` - -## The Shared Koin module - -Use the `module` function to declare a Koin module. A Koin module is the place where we define all our components to be injected. - -Let's declare our first component. We want a singleton of `UserRepository`, by creating an instance of `UserRepositoryImpl` - -```kotlin -module { - single { UserRepositoryImpl() } -} -``` - -## The Shared Presenter - -Let's write a presenter component to display a user: - -```kotlin -class KMPUserPresenter(private val repository: UserRepository) { - - fun sayHello() : String { - val name = DefaultData.DEFAULT_USER.name - val foundUser = repository.findUser(name) - return foundUser?.let { "Hello '$it' from $this" } ?: "User '$name' not found!" - } -} -``` - -> UserRepository is referenced in UserPresenter`s constructor - -We declare `UserPresenter` in our Koin module. We declare it as a `factory` definition, to not keep any instance in memory and let the native system hold it: - -```kotlin -fun appModule() = module { - single { UserRepositoryImpl() } - factory { KMPUserPresenter(get()) } -} -``` - -:::note -The Koin module is available as function to run (`appModule()` here), to be easily runned from iOS side, with `initKoin()` function. -::: - -## Injecting Dependencies in Android - -> All the Android app is located in `androidApp` Gradle project - -The `KMPUserPresenter` component will be created, resolving the `UserRepository` instance with it. To get it into our Activity, let's inject it with the `by inject()` delegate function: - -```kotlin -class MainActivity : AppCompatActivity() { - - private val presenter: UserPresenter by inject() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - //... - } -} -``` - -That's it, your app is ready. - -:::info -The `by inject()` function allows us to retrieve Koin instances, in Android components runtime (Activity, fragment, Service...) -::: - -We need to start Koin with our Android application. Just call the `startKoin()` function in the application's main entry point, our `MainApplication` class: - -```kotlin -class MainApplication : Application() { - - private val userRepository : UserRepository by inject() - - override fun onCreate() { - super.onCreate() - - startKoin { - androidContext(this@MainApplication) - androidLogger() - modules(appModule() + androidModule) - } - - userRepository.addUsers(DefaultData.DEFAULT_USERS) - } -} -``` - -:::info -The `modules()` function in `startKoin` load the given list of modules -::: - - -## Injecting Dependencies in iOS - -> All the iOS app is located in `iosApp` folder - -The `KMPUserPresenter` component will be created, resolving the `UserRepository` instance with it. To get it into our `ContentView`, we need to create a Helper class to boostrap Koin dependencies: - -```kotlin -class KMPUserPresenterHelper : KoinComponent { - - private val userPresenter : KMPUserPresenter by inject() - - fun sayHello(): String = userPresenter.sayHello() -} -``` - -That's it, you can just call `sayHello()` function from iOS part. - -```swift -import shared - -struct ContentView: View { - let helloText = KMPUserPresenterHelper().sayHello() - - var body: some View { - Text(helloText) - } -} -``` - -We need to start Koin with our iOS application. In the Kotlin shared code, we have a function to let us configure Koin (and setup default data): - -```kotlin -// in HelperKt.kt - -fun initKoin() { - // start Koin - val koinApp = startKoin { - modules(appModule()) - }.koin - - // load default users - koinApp.get().addUsers(DefaultData.DEFAULT_USERS) -} -``` - -Finally in the iOS main entry, we can call the `HelperKt.doInitKoin()` function that is calling our helper function above. - -```swift -@main -struct iOSApp: App { - - init() { - HelperKt.doInitKoin() - } - - //... -} -``` - - diff --git a/projects/docs/quickstart/kotlin-annotations.md b/projects/docs/quickstart/kotlin-annotations.md deleted file mode 100755 index 1d48c4708..000000000 --- a/projects/docs/quickstart/kotlin-annotations.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -title: Kotlin - Annotations ---- - -> This tutorial lets you write a Kotlin application and use Koin dependency injection to retrieve your components. -> You need around __10 min__ to do the tutorial. - -## Get the code - -:::info -[The source code is available at on Github](https://github.com/InsertKoinIO/koin-getting-started/tree/main/kotlin-annotations) -::: - -## Setup - -Let's configure the KSP plugin like below in Gradle: - -```groovy -plugins { - // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. - id 'org.jetbrains.kotlin.jvm' version "$kotlin_version" - // Apply the application plugin to add support for building a CLI application in Java. - id "com.google.devtools.ksp" version "$ksp_version" - id 'application' -} - -// KSP - To use generated sources -sourceSets.main { - java.srcDirs("build/generated/ksp/main/kotlin") -} -``` - -Let's setup the dependencies like below: - -```groovy -dependencies { - - // Koin - implementation "io.insert-koin:koin-core:$koin_version" - implementation "io.insert-koin:koin-annotations:$koin_ksp_version" - ksp "io.insert-koin:koin-ksp-compiler:$koin_ksp_version" -} -``` - -## Application Overview - -The idea of the application is to manage a list of users, and display it in our `UserApplication` class: - -> Users -> UserRepository -> UserService -> UserApplication - -## The "User" Data - -We will manage a collection of Users. Here is the data class: - -```kotlin -data class User(val name : String) -``` - -We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the `UserRepository` interface and its implementation: - -```kotlin -interface UserRepository { - fun findUser(name : String): User? - fun addUsers(users : List) -} - -class UserRepositoryImpl : UserRepository { - - private val _users = arrayListOf() - - override fun findUser(name: String): User? { - return _users.firstOrNull { it.name == name } - } - - override fun addUsers(users : List) { - _users.addAll(users) - } -} -``` - -## The Koin module - -Let's declare a `AppModule` module class like below. - -```kotlin -@Module -@ComponentScan("org.koin.sample") -class AppModule -``` - -* We use the `@Module` to declare our class as Koin module -* The `@ComponentScan("org.koin.sample")` allow to scann any Koin definition in `"org.koin.sample"`package - -Let's simply add `@Single` on `UserRepositoryImpl` class to declare it as singleton: - -```kotlin -@Single -class UserRepositoryImpl : UserRepository { - // ... -} -``` - -## The UserService Component - -Let's write the UserService component to request the default user: - -```kotlin -class UserService(private val userRepository: UserRepository) { - - fun getDefaultUser() : User = userRepository.findUser(DefaultData.DEFAULT_USER.name) ?: error("Can't find default user") -} -``` - -> UserRepository is referenced in UserPresenter`s constructor - -Let's simply add `@Single` on `UserService` class to declare it as singleton: - -```kotlin -@Single -class UserService(private val userRepository: UserRepository) { - // ... -} -``` - -## Injecting Dependencies in UserApplication - -The `UserApplication` class will help bootstrap instances out of Koin. It will resolve the `UserService`, thanks to `KoinComponent` interface. This allows to inject it with the `by inject()` delegate function: - -```kotlin -class UserApplication : KoinComponent { - - private val userService : UserService by inject() - - // display our data - fun sayHello(){ - val user = userService.getDefaultUser() - val message = "Hello '$user'!" - println(message) - } -} -``` - -That's it, your app is ready. - -:::info -The `by inject()` function allows us to retrieve Koin instances, in any class that extends `KoinComponent` -::: - - -## Start Koin - -We need to start Koin with our application. Just call the `startKoin()` function in the application's main entry point, our `main` function: - -```kotlin -// generated -import org.koin.ksp.generated.* - -fun main() { - startKoin { - modules(AppModule().module) - } - - UserApplication().sayHello() -} -``` - -The Koin module is generated from `AppModule` with the `.module` extension: Just use the `AppModule().module` expression to get the Koin module from the annotations. - - -:::info -The `import org.koin.ksp.generated.*` import is required to allow to use generated Koin module content -::: - -## Compile Time Checks - -Koin Annotations allows to check your Koin configuration at compile time. This is available by jusing the following Gradle option: - -```groovy -ksp { - arg("KOIN_CONFIG_CHECK","true") -} -``` \ No newline at end of file diff --git a/projects/docs/quickstart/kotlin.md b/projects/docs/quickstart/kotlin.md deleted file mode 100755 index c9c70f087..000000000 --- a/projects/docs/quickstart/kotlin.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -title: Kotlin ---- - -> This tutorial lets you write a Kotlin application and use Koin dependency injection to retrieve your components. -> You need around __10 min__ to do the tutorial. - -## Get the code - -:::info -[The source code is available at on Github](https://github.com/InsertKoinIO/koin-getting-started/tree/main/kotlin) -::: - -## Setup - -First, check that the `koin-core` dependency is added like below: - -```groovy -dependencies { - - // Koin for Kotlin apps - compile "io.insert-koin:koin-core:$koin_version" -} -``` - -## Application Overview - -The idea of the application is to manage a list of users, and display it in our `UserApplication` class: - -> Users -> UserRepository -> UserService -> UserApplication - -## The "User" Data - -We will manage a collection of Users. Here is the data class: - -```kotlin -data class User(val name : String) -``` - -We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the `UserRepository` interface and its implementation: - -```kotlin -interface UserRepository { - fun findUser(name : String): User? - fun addUsers(users : List) -} - -class UserRepositoryImpl : UserRepository { - - private val _users = arrayListOf() - - override fun findUser(name: String): User? { - return _users.firstOrNull { it.name == name } - } - - override fun addUsers(users : List) { - _users.addAll(users) - } -} -``` - -## The Koin module - -Use the `module` function to declare a Koin module. A Koin module is the place where we define all our components to be injected. - -```kotlin -val appModule = module { - -} -``` - -Let's declare our first component. We want a singleton of `UserRepository`, by creating an instance of `UserRepositoryImpl` - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } -} -``` - -## The UserService Component - -Let's write the UserService component to request the default user: - -```kotlin -class UserService(private val userRepository: UserRepository) { - - fun getDefaultUser() : User = userRepository.findUser(DefaultData.DEFAULT_USER.name) ?: error("Can't find default user") -} -``` - -> UserRepository is referenced in UserPresenter`s constructor - -We declare `UserService` in our Koin module. We declare it as a `single` definition: - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } - single { UserService(get()) } -} -``` - -> The `get()` function allow to ask Koin to resolve the needed dependency. - -## Injecting Dependencies in UserApplication - -The `UserApplication` class will help bootstrap instances out of Koin. It will resolve the `UserService`, thanks to `KoinComponent` interface. This allows to inject it with the `by inject()` delegate function: - -```kotlin -class UserApplication : KoinComponent { - - private val userService : UserService by inject() - - // display our data - fun sayHello(){ - val user = userService.getDefaultUser() - val message = "Hello '$user'!" - println(message) - } -} -``` - -That's it, your app is ready. - -:::info -The `by inject()` function allows us to retrieve Koin instances, in any class that extends `KoinComponent` -::: - - -## Start Koin - -We need to start Koin with our application. Just call the `startKoin()` function in the application's main entry point, our `main` function: - -```kotlin -fun main() { - startKoin { - modules(appModule) - } - - UserApplication().sayHello() -} -``` - -:::info -The `modules()` function in `startKoin` load the given list of modules -::: - -## Koin module: classic or constructor DSL? - -Here is the Koin moduel declaration for our app: - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } - single { UserService(get()) } -} -``` - -We can write it in a more compact way, by using constructors: - -```kotlin -val appModule = module { - singleOf(::UserRepositoryImpl) { bind() } - singleOf(::UserService) -} -``` diff --git a/projects/docs/quickstart/ktor.md b/projects/docs/quickstart/ktor.md deleted file mode 100755 index 5806c43d7..000000000 --- a/projects/docs/quickstart/ktor.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -title: Ktor ---- - -> Ktor is a framework for building asynchronous servers and clients in connected systems using the powerful Kotlin programming language. We will use Ktor here, to build a simple web application. - -Let's go 🚀 - -## Get the code - -:::info -[The source code is available at on Github](https://github.com/InsertKoinIO/koin-getting-started/tree/main/ktor) -::: - -## Gradle Setup - -First, add the Koin dependency like below: - -```kotlin -dependencies { - // Koin for Kotlin apps - implementation "io.insert-koin:koin-ktor:$koin_version" - implementation "io.insert-koin:koin-logger-slf4j:$koin_version" -} -``` - -## Application Overview - -The idea of the application is to manage a list of users, and display it in our `UserApplication` class: - -> Users -> UserRepository -> UserService -> UserApplication - -## The "User" Data - -We will manage a collection of Users. Here is the data class: - -```kotlin -data class User(val name : String) -``` - -We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the `UserRepository` interface and its implementation: - -```kotlin -interface UserRepository { - fun findUser(name : String): User? - fun addUsers(users : List) -} - -class UserRepositoryImpl : UserRepository { - - private val _users = arrayListOf() - - override fun findUser(name: String): User? { - return _users.firstOrNull { it.name == name } - } - - override fun addUsers(users : List) { - _users.addAll(users) - } -} -``` - -## The Koin module - -Use the `module` function to declare a Koin module. A Koin module is the place where we define all our components to be injected. - -```kotlin -val appModule = module { - -} -``` - -Let's declare our first component. We want a singleton of `UserRepository`, by creating an instance of `UserRepositoryImpl` - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } -} -``` - -## The UserService Component - -Let's write the UserService component to request the default user: - -```kotlin -class UserService(private val userRepository: UserRepository) { - - fun getDefaultUser() : User = userRepository.findUser(DefaultData.DEFAULT_USER.name) ?: error("Can't find default user") -} -``` - -> UserRepository is referenced in UserPresenter`s constructor - -We declare `UserService` in our Koin module. We declare it as a `single` definition: - -```kotlin -val appModule = module { - single { UserRepositoryImpl() } - single { UserService(get()) } -} -``` - -## HTTP Controller - -Finally, we need an HTTP Controller to create the HTTP Route. In Ktor is will be expressed through an Ktor extension function: - -```kotlin -fun Application.main() { - - // Lazy inject HelloService - val service by inject() - - // Routing section - routing { - get("/hello") { - call.respondText(service.sayHello()) - } - } -} -``` - -Check that your `application.conf` is configured like below, to help start the `Application.main` function: - -```kotlin -ktor { - deployment { - port = 8080 - - // For dev purpose - //autoreload = true - //watch = [org.koin.sample] - } - - application { - modules = [ org.koin.sample.UserApplicationKt.main ] - } -} -``` - -## Declare your dependencies - -Let's assemble our components with a Koin module: - -```kotlin -val appModule = module { - singleOf(::UserRepositoryImpl) { bind() } - singleOf(::UserService) -} -``` - -## Start and Inject - -Finally, let's start Koin from Ktor: - -```kotlin -fun Application.main() { - install(Koin) { - slf4jLogger() - modules(appModule) - } - - // Lazy inject HelloService - val service by inject() - service.saveDefaultUsers() - - // Routing section - routing { - get("/hello") { - call.respondText(service.sayHello()) - } - } -} -``` - -Let's start Ktor: - -```kotlin -fun main(args: Array) { - // Start Ktor - embeddedServer(Netty, commandLineEnvironment(args)).start(wait = true) -} -``` - -That's it! You're ready to go. Check the `http://localhost:8080/hello` url! diff --git a/projects/docs/resources/articles.md b/projects/docs/resources/articles.md deleted file mode 100644 index 5f042cbe8..000000000 --- a/projects/docs/resources/articles.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Articles ---- - -* [Dagger is dead. Long live Koin](https://www.linkedin.com/pulse/dagger-dead-long-live-koin-yordan-olave-cordero) -* [Testing a Koin application with KotlinTest](https://dev.to/kerooker/testing-koin-applications-with-kotlintest-1iip) -* [Ready for Koin 2.0](https://medium.com/koin-developers/ready-for-koin-2-0-2722ab59cac3) -* [Migration from Dagger2 to Koin](https://proandroiddev.com/migrating-from-dagger2-to-koin-3b2b3f5285e9) -* [From Dagger to Koin, a step-by-step migration guide](https://medium.com/@giuliani.arnaud/the-thermosiphon-app-from-dagger-to-koin-step-by-step-a09af7f5b5b1) -* [Koin in Feature Modules Project](https://proandroiddev.com/koin-in-feature-modules-project-6329f069f943) -* [A brief look at Koin on Android](https://overflow.buffer.com/2018/09/13/a-brief-look-at-koin-on-android/) -* [Bye bye Dagger](https://medium.com/@charbgr/bye-bye-dagger-1494118dcd41) -* [Testing with Koin](https://proandroiddev.com/testing-with-koin-ade8a46eb4d) -* [Painless Android testing with Room & Koin](https://android.jlelse.eu/painless-android-testing-with-room-koin-bb949eefcbee) -* [Unlock your Android ViewModel power with Koin](https://medium.com/@giuliani.arnaud/unlock-your-android-viewmodel-power-with-koin-23eda8f493be) -* [Using dependency injection with Koin](https://medium.com/mindorks/using-dependency-injection-with-koin-bee0b461714a) -* [Push SparkJava to the next level](https://medium.com/koin-developers/pushing-sparkjava-to-the-next-level-with-koin-ed1f0b80953e) ([Kotlin Weekly issue 73](http://mailchi.mp/kotlinweekly/kotlin-weekly-73), [DZone.com](https://dzone.com/articles/push-sparkjava-to-the-next-level-with-koin) ) -* [When Koin met Ktor ...](https://medium.com/koin-developers/when-koin-met-ktor-c3b2395662bf) ([Kotlin Weekly issue 72](https://us12.campaign-archive.com/?u=f39692e245b94f7fb693b6d82&id=3135ae0cf5)) -* [Android Dependency Injection – Why we moved from Dagger 2 to Koin?](https://www.nan-labs.com/blog/android-dependency-injection-moved-dagger-2-koin/) -* [Moving from Dagger to Koin - Simplify your Android development](https://medium.com/@giuliani.arnaud/moving-from-dagger-to-koin-simplify-your-android-development-e8c61d80cddb) - ([Kotlin Weekly issue 66](http://mailchi.mp/kotlinweekly/kotlin-weekly-66?e=e8a57c719f) & [Android Weekly issue 282](http://androidweekly.net/issues/issue-282)) -* [Kotlin Weekly #64](http://mailchi.mp/kotlinweekly/kotlin-weekly-64?e=e8a57c719f) -* [Better dependency injection for Android](https://proandroiddev.com/better-dependency-injection-for-android-567b93353ad) \ No newline at end of file diff --git a/projects/docs/resources/index.md b/projects/docs/resources/index.md deleted file mode 100644 index 79e0feb14..000000000 --- a/projects/docs/resources/index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Koin Developer Hub ---- - -* [What’s next with Koin? — 2.2 & 3.0 releases](https://medium.com/koin-developers/whats-next-with-koin-2-2-3-0-releases-6c5464ae5e3d) -* [Unboxing Koin 2.1](https://medium.com/koin-developers/unboxing-koin-2-1-7f1133ebb790) -* [Ready for Koin 2.0](https://medium.com/koin-developers/ready-for-koin-2-0-2722ab59cac3) -* [News from the trenches, What's next for Koin?](https://medium.com/koin-developers/news-from-the-trenches-whats-next-for-koin-994791d572d5) -* [Koin 1.0.0 Unleashed](https://medium.com/koin-developers/koin-1-0-0-unleashed-dcc15b293a3a) -* [Opening Koin 1.0.0 Beta](https://medium.com/koin-developers/opening-the-koin-1-0-0-beta-version-99cb8be1c308) -* [On the road to Koin 1.0](https://medium.com/koin-developers/on-the-road-to-koin-1-0-0-a624af55d07) -* [Koin 0.9.2 — Maintenance fixes, new branding, roadmap for 1.0.0 & some other nice announces](https://medium.com/koin-developers/koin-0-9-2-maintenance-fixes-new-branding-roadmap-for-1-0-0-some-other-nice-announces-94f14648e4ad) -* [Koin 0.9.1 - Bug fixes & Improvements](https://medium.com/koin-developers/koin-0-9-1-bug-fixes-improvements-bug-fixes-d257cd2766fa) -* [Koin 0.9.0 - Getting close to stable](https://medium.com/koin-developers/koin-0-9-0-getting-close-to-stable-release-74df9bb9e181) -* [Unlock your Android ViewModel power with Koin](https://medium.com/@giuliani.arnaud/unlock-your-android-viewmodel-power-with-koin-23eda8f493be) -* [koin 0.8.2 Improvements bugfixes and crash fix](https://medium.com/koin-developers/koin-0-8-2-improvements-bugfixes-and-crash-fix-6b6809fc1dd2) -* [Koin release 0.8.0](https://medium.com/koin-developers/koin-released-in-0-8-0-welcome-to-koin-spark-koin-android-architecture-f6270a7d4808) - diff --git a/projects/docs/resources/videos.md b/projects/docs/resources/videos.md deleted file mode 100644 index 0ffee2327..000000000 --- a/projects/docs/resources/videos.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Talk and Conferences ---- - -* [Dependency Injection For Kotlin apps with Koin, Kotlin London 2019, London](https://www.youtube.com/watch?v=z_wTkxSKzzY) -* [Dependency Injection from zero to hero with Koin, Kotliners 2019 & Budapest, Hungary](https://www.youtube.com/watch?v=mt9yoWScgb8&list=PLnYRVL0Cw1FSUJ-WdhV2Ija9kA9q0qP3e&index=6) -* [Dependency Injection from zero to hero with Koin, Kotliners 2019 & Budapest, Hungary](https://www.youtube.com/watch?v=mt9yoWScgb8&list=PLnYRVL0Cw1FSUJ-WdhV2Ija9kA9q0qP3e&index=6) -* [Dependency Injection from zero to hero with Koin, AndroidMakers 2019 & Paris, France](https://www.youtube.com/watch?v=chCsNkjotfc) -* [Simplify your Android development with Koin - Mobilization @ Lodz 2018, Poland](https://www.youtube.com/watch?v=KzQbJFVjr9w&t=1s) -* [Talking Kotlin - Dependency injection with Koin - 2018](http://talkingkotlin.com/dependency-injection-with-koin/) -* [L'injection de poireaux avec Koin - AndroidLeaks ep42 (French)](https://androidleakspodcast.com/2018/08/05/episode-42-linjection-de-poireaux-avec-koin/) -* [Insert Koin. Mobile Fest 2018, Kiev, Ukraine (Russian)](https://youtu.be/HrTz5jToQkk) diff --git a/projects/docs/setup/koin.md b/projects/docs/setup/koin.md deleted file mode 100644 index 5fc2a4e66..000000000 --- a/projects/docs/setup/koin.md +++ /dev/null @@ -1,224 +0,0 @@ ---- -title: Koin ---- - -All you need to setting up Koin in your project - -## Current Versions - -You can find all Koin packages on [maven central](https://search.maven.org/search?q=io.insert-koin). - -Here are the currently available versions: - -| Project | Version | -|----------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| koin-bom | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-bom)](https://mvnrepository.com/artifact/io.insert-koin/koin-bom) | -| koin-core | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-core)](https://mvnrepository.com/artifact/io.insert-koin/koin-core) | -| koin-core-coroutines | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-core-coroutines)](https://mvnrepository.com/artifact/io.insert-koin/koin-core-coroutines) | -| koin-test | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-test)](https://mvnrepository.com/artifact/io.insert-koin/koin-test) | -| koin-android | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-android)](https://mvnrepository.com/artifact/io.insert-koin/koin-android) | -| koin-android-test | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-android-test)](https://mvnrepository.com/artifact/io.insert-koin/koin-android-test) | -| koin-android-compat | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-android-compat)](https://mvnrepository.com/artifact/io.insert-koin/koin-android-compat) | -| koin-androidx-navigation | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-androidx-navigation)](https://mvnrepository.com/artifact/io.insert-koin/koin-androidx-navigation) | -| koin-androidx-workmanager | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-androidx-workmanager)](https://mvnrepository.com/artifact/io.insert-koin/koin-androidx-workmanager) | -| koin-compose | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-compose)](https://mvnrepository.com/artifact/io.insert-koin/koin-compose) | -| koin-androidx-compose | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-androidx-compose)](https://mvnrepository.com/artifact/io.insert-koin/koin-androidx-compose) | -| koin-androidx-compose-navigation | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-androidx-compose-navigation)](https://mvnrepository.com/artifact/io.insert-koin/koin-androidx-compose-navigation) | -| koin-ktor | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-ktor)](https://mvnrepository.com/artifact/io.insert-koin/koin-ktor) | -| koin-logger-slf4j | [![Maven Central](https://img.shields.io/maven-central/v/io.insert-koin/koin-logger-slf4j)](https://mvnrepository.com/artifact/io.insert-koin/koin-logger-slf4j) | - -## Gradle Setup - -### Kotlin - -Starting from 3.5.0 you can use BOM-version to manage all Koin library versions. When using the BOM in your app, you don't need to add any version to the Koin library dependencies themselves. When you update the BOM version, all the libraries that you're using are automatically updated to their new versions. - -Add `koin-bom` BOM and `koin-core` dependency to your application: -```kotlin -implementation(platform("io.insert-koin:koin-bom:$koin_version")) -implementation("io.insert-koin:koin-core") -``` -If you are using version catalogs: -```toml -[versions] -koin-bom = "x.x.x" -... - -[libraries] -koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koin-bom" } -koin-core = { module = "io.insert-koin:koin-core" } -... -``` -```kotlin -dependencies { - implementation(platform(libs.koin.bom)) - implementation(libs.koin.core) -} -``` - -Or use an old way of specifying the exact dependency version for Koin: -```kotlin -dependencies { - implementation("io.insert-koin:koin-core:$koin_version") -} -``` - -You are now ready to start Koin: - -```kotlin -fun main() { - startKoin { - modules(...) - } -} -``` - -If you need testing capacity: - -```groovy -dependencies { - // Koin Test features - testImplementation("io.insert-koin:koin-test:$koin_version") - // Koin for JUnit 4 - testImplementation("io.insert-koin:koin-test-junit4:$koin_version") - // Koin for JUnit 5 - testImplementation("io.insert-koin:koin-test-junit5:$koin_version") -} -``` - -:::info -From now you can continue on Koin Tutorials to learn about using Koin: [Kotlin App Tutorial](/docs/quickstart/kotlin) -::: - -### **Android** - -Add `koin-android` dependency to your Android application: - -```groovy -dependencies { - implementation("io.insert-koin:koin-android:$koin_android_version") -} -``` - -You are now ready to start Koin in your `Application` class: - -```kotlin -class MainApplication : Application() { - override fun onCreate() { - super.onCreate() - - startKoin { - modules(appModule) - } - } -} -``` - -If you need extra features, add the following needed package: - -```groovy -dependencies { - // Java Compatibility - implementation("io.insert-koin:koin-android-compat:$koin_android_version") - // Jetpack WorkManager - implementation("io.insert-koin:koin-androidx-workmanager:$koin_android_version") - // Navigation Graph - implementation("io.insert-koin:koin-androidx-navigation:$koin_android_version") -} -``` - -:::info -From now you can continue on Koin Tutorials to learn about using Koin: [Android App Tutorial](/docs/quickstart/android-viewmodel) -::: - -### **Android Jetpack Compose** - -```groovy -dependencies { - implementation("io.insert-koin:koin-androidx-compose:$koin_android_compose_version") -} -``` - -You are now ready to start Koin in your `Application` class: - -```kotlin -class MainApplication : Application() { - override fun onCreate() { - super.onCreate() - - startKoin { - modules(appModule) - } - } -} -``` - -:::info -From now you can continue on Koin Tutorials to learn about using Koin: [Android Compose App Tutorial](/docs/quickstart/android-compose) -::: - - -### **Kotlin Multiplatform** - -Add `koin-core` dependency to your multiplatform application, for shared Kotlin part: - -```groovy -dependencies { - implementation("io.insert-koin:koin-core:$koin_version") -} -``` - -:::info -From now you can continue on Koin Tutorials to learn about using Koin: [Kotlin Multiplatform App Tutorial](/docs/quickstart/kmm) -::: - -### **Ktor** - -Add `koin-ktor` dependency to your Ktor application: - -```groovy -dependencies { - // Koin for Ktor - implementation("io.insert-koin:koin-ktor:$koin_ktor") - // SLF4J Logger - implementation("io.insert-koin:koin-logger-slf4j:$koin_ktor") -} -``` - -You are now ready to install Koin feature into your Ktor application: - -```kotlin -fun Application.main() { - install(Koin) { - slf4jLogger() - modules(appModule) - } -} -``` - -:::info -From now you can continue on Koin Tutorials to learn about using Koin: [Ktor App Tutorial](/docs/quickstart/ktor) -::: - - -### **Koin BOM** -The Koin Bill of Materials (BOM) lets you manage all of your Koin library versions by specifying only the BOM’s version. The BOM itself has links to the stable versions of the different Koin libraries, in such a way that they work well together. When using the BOM in your app, you don't need to add any version to the Koin library dependencies themselves. When you update the BOM version, all the libraries that you're using are automatically updated to their new versions. - -```groovy -dependencies { - // Declare koin-bom version - implementation platform("io.insert-koin:koin-bom:$koin_bom") - - // Declare the koin dependencies that you need - implementation("io.insert-koin:koin-android") - implementation("io.insert-koin:koin-core-coroutines") - implementation("io.insert-koin:koin-androidx-workmanager") - - // If you need specify some version it's just point to desired version - implementation("io.insert-koin:koin-androidx-navigation:1.2.3-alpha03") - - // Works with test libraries too! - testImplementation("io.insert-koin:koin-test-junit4") - testImplementation("io.insert-koin:koin-android-test") -} -``` diff --git a/projects/docs/setup/why.md b/projects/docs/setup/why.md deleted file mode 100644 index d1f2ea004..000000000 --- a/projects/docs/setup/why.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: Why Koin? ---- - -Koin provides an easy and efficient way to incorporate dependency injection into any Kotlin application(Multiplatform, Android, backend ...) - -The goals of Koin are: -- Simplify your Dependency Injection infrastructure with smart API -- Kotlin DSL easy to read, easy to use, to let you write any kind of application -- Provides different kind of integration from Android ecosystem, to more backend needs like Ktor -- Allow to be used with annotations - -## Koin in a nutshell - -### Making your Kotlin development easy and productive - -Koin is a smart Kotlin dependency injection library to keep you focused on your app, not on your tools. - -```kotlin - -class MyRepository() -class MyPresenter(val repository : MyRepository) - -// just declare it -val myModule = module { - singleOf(::MyPresenter) - singleOf(::MyRepository) -} -``` - -Koin gives you simple tools and API to let you build, assemble Kotlin related technologies into your application and let you scale your business with easiness. - -```kotlin -fun main() { - - // Just start Koin - startKoin { - modules(myModule) - } -} -``` - -### Ready for Android - -Thanks to the Kotlin language, Koin extends the Android platform and provides new features as part of the original platform. - -```kotlin -class MyApplication : Application() { - override fun onCreate() { - super.onCreate() - - startKoin { - modules(myModule) - } - } -} -``` - -Koin provides easy and powerful API to retrieve your dependencies anywhere in Android components, with just using by inject() or by viewModel() - -```kotlin -class MyActivity : Application() { - - val myPresenter : MyPresenter by inject() - -} -``` - -### Powering Kotlin Multiplatform - -Sharing code between mobile platforms is one of the major Kotlin Multiplatform use cases. With Kotlin Multiplatform Mobile, you can build cross-platform mobile applications and share common code between Android and iOS. - -Koin provides multiplatform dependency injection and help build your components across your native mobile applications, and web/backend applications. - -### Performances and Productivity - -Koin is a pure Kotlin framework, designed to be straight forward in terms of usage and execution. It easy to use and doesn't impact your compilation time, nor require any extra plugin configuration. - -## Koin: A Dependency Injection Framework - -Koin is a popular dependency injection (DI) framework for Kotlin, offering a modern and lightweight solution for managing your application’s dependencies with minimal boilerplate code. - -### Dependency Injection vs. Service Locator - -While Koin may appear similar to a service locator pattern, there are key differences that set it apart: - -- Service Locator: A service locator is essentially a registry of available services where you can request an instance of a service as needed. It is responsible for creating and managing these instances, often using a static, global registry. - -- Dependency Injection: In contrast, Koin is a pure dependency injection framework. With Koin, you declare your dependencies in modules, and Koin handles the creation and wiring of objects. It allows for the creation of multiple, independent modules with their own scopes, making dependency management more modular and avoiding potential conflicts. - -### Koin’s Approach: A Blend of Flexibility and Best Practices - -Koin supports both DI and the Service Locator pattern, offering flexibility to developers. However, it strongly encourages the use of DI, particularly constructor injection, where dependencies are passed as constructor parameters. This approach promotes better testability and makes your code easier to reason about. - -Koin’s design philosophy is centered around simplicity and ease of setup while allowing for complex configurations when necessary. By using Koin, developers can manage dependencies effectively, with DI being the recommended and preferred approach for most scenarios. - - -### Transparency and Design Overview - -Koin is designed to be a versatile Inversion of Control (IoC) container that supports both Dependency Injection (DI) and Service Locator (SL) patterns. To provide a clear understanding of how Koin operates and to guide you in using it effectively, let’s explore the following aspects: - -#### How Koin Balances DI and SL - -Koin combines elements of both DI and SL, which may influence how you use the framework: - -1. **Global Context Usage:** By default, Koin provides a globally accessible component that acts like a service locator. This allows you to retrieve dependencies from a central registry using `KoinComponent` or `inject` functions. - -2. **Isolated Components:** Although Koin encourages the use of Dependency Injection, particularly constructor injection, it also allows for isolated components. This flexibility means you can configure your application to use DI where it makes the most sense while still taking advantage of SL for specific cases. - -3. **SL in Android Components:** In Android development, Koin often uses SL internally within components such as `Application` and `Activity` for ease of setup. From this point, Koin recommends DI, especially constructor injection, to manage dependencies in a more structured way. However, this is not enforced, and developers have the flexibility to use SL if needed. - -#### Why This Matters to You - -Understanding the distinction between DI and SL helps in managing your application’s dependencies effectively: - -- **Dependency Injection:** Encouraged by Koin for its benefits in testability and maintainability. Constructor injection is preferred as it makes dependencies explicit and enhances code clarity. - -- **Service Locator:** While Koin supports SL for convenience, especially in Android components, relying solely on SL can lead to tighter coupling and reduced testability. Koin’s design provides a balanced approach, allowing you to use SL where it’s practical but promoting DI as the best practice. - -#### Making the Most of Koin - -To use Koin effectively: - -- **Follow Best Practices:** Use constructor injection where possible to align with best practices for dependency management. This approach improves testability and maintainability. - -- **Leverage Koin’s Flexibility:** Utilize Koin’s support for SL in scenarios where it simplifies setup, but aim to rely on DI for managing core application dependencies. - -- **Refer to Documentation and Examples:** Review Koin’s documentation and examples to understand how to configure and use DI and SL appropriately based on your project needs. - -- **Visualize Dependency Management:** Diagrams and examples can help illustrate how Koin resolves dependencies and manages them within different contexts. These visual aids can provide a clearer understanding of Koin’s internal workings. - -> By providing this guidance, we aim to help you navigate Koin’s features and design choices effectively, ensuring you can leverage its full potential while adhering to best practices in dependency management. \ No newline at end of file diff --git a/projects/docs/support/index.md b/projects/docs/support/index.md deleted file mode 100644 index 2257aa91f..000000000 --- a/projects/docs/support/index.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Roadmap & Support -custom_edit_url: null ---- - -The Koin team is leading its development with open-source and community-driven approach since the beginning, and propose commercial services to secure your development. - -## Releases Cycle - -We drive our developments with release cycles of 6 months to follow Kotlin language and library updates in a consistent manner. We will use beta periods of 6 weeks or more, to help gather first feedbacks. - -Once a new version is released, we start the Community support phase for 6 months minimum. During that phase, we are actively gathering feedbacks, following all updates impacting our framework, like librairies, Kotling Android, Ktor and others frameworks versions. - -## Establishing Roadmap with Structured Versions - -The first big thing for the Koin project is organizing release cycles to establish a clear vision on versions deployment, and to help you anticipate updates and new features. We need a clear version tracking: `Major.Minor.Patch` - -- Patch version: fixes only, minor dependency library updates -- Minor version: New features & deprecations -- Major features: New Impacting features, deprecations & hard breaking - -We now drive our developments with release cycles of 6 months to follow Kotlin language and library updates in a consistent manner. We will use beta periods of 6 weeks to help gather first feedbacks. - -## Community or Commercial Support - -Behind our will to build a vision with a roadmap, we also know that many companies are engaging their business while they are using Koin to build their solutions and applications. - -[Kotzilla](https://www.kotzilla.io/), the company of the authors of Koin, propose strong corporate support: [long-term support versions](https://www.kotzilla.io/support/). - -## Roadmap for 2022 - -Here is our current roadmap: - -![](/img/roadmap_2022.png) - -- Koin 3.1 (Q1) -- Koin 3.2 (Q2) -- Koin 3.3 (Q4) -- Koin Annotations 1.0 (Q2) - - - diff --git a/projects/docs/upgrade/migrate.md b/projects/docs/upgrade/migrate.md deleted file mode 100644 index 44dbbd86e..000000000 --- a/projects/docs/upgrade/migrate.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Migration Guide ---- - -The new branch of Koin 3.x is bringing latest features & fixes. It brings Multiplatform, Jetpack Compose and much more. You can use it even if you don't use those features, to benefit from the latest fixes. - -## Migrating to latest version 🚀 - -### Koin v2 - -#### Android & AndroidX Module - -The following modules are available for Android. Be sure to use the `koin-androidx` modules, as there are based on the latest AndroidX library support: - -```groovy -// Koin AndroidX Scope features -implementation "io.insert-koin:koin-androidx-scope:$koin_version" -// Koin AndroidX ViewModel features -implementation "io.insert-koin:koin-androidx-viewmodel:$koin_version" -// Koin AndroidX Fragment features -implementation "io.insert-koin:koin-androidx-fragment:$koin_version" -// Koin AndroidX WorkManager -implementation "io.insert-koin:koin-androidx-workmanager:$koin_version" -// Koin AndroidX Jetpack Compose -implementation "io.insert-koin:koin-androidx-compose:$koin_version" -// Koin AndroidX Experimental features -implementation "io.insert-koin:koin-androidx-ext:$koin_version" -``` - -### Koin v3 - -The new Koin core is now Multiplatform. You can use it even if your project is not Kotlin Multiplatform. - -#### Reimporting for new API - -If you have seen unresolved Koin API import, you can try to remove/reimport the used API as some packages has been moved in the Koin core module. See new section - -#### Kotlin Core & JVM features - -KoinComponent and linked extension have been moved to package `org.koin.core.component`. Please reimport related APIs (`KoinComponent`,`inject`, `get`...). - -Java/JVM Specific API are isolated in `koin-core-jvm` part of Koin core. Here are the following components: - -- PropertyRegistry: - - `saveProperties` - - `loadPropertiesFromFile` - - `loadEnvironmentProperties` - -- KoinJavaComponent - -- KoinApplication: - - `fileProperties` - - `environmentProperties` - -- Scope extensions for Java: - - `org.koin.core.scope.ScopeJVMKt` - -#### Android Modules - -In v3, the `koin-android` modules is using AndroidX API, and merge also all Scope/Fragment/ViewModel API. You don't need anymore to specify `koin-androidx-fragment`, `koin-androidx-viewmodel` or `koin-androidx-scope` as there are all in the `koin-android` module: - -```groovy -// Koin main features for Android (Scope,ViewModel ...) -implementation "io.insert-koin:koin-android:$koin_version" -// Koin Java Compatibility -implementation "io.insert-koin:koin-android-compat:$koin_version" -// Koin for Jetpack WorkManager -implementation "io.insert-koin:koin-androidx-workmanager:$koin_version" -// Koin for Jetpack Compose -implementation "io.insert-koin:koin-androidx-compose:$koin_version" -``` - -Java Compat API has been extracted in `koin-android-compat` module. diff --git a/projects/docs/upgrade/whats-new.md b/projects/docs/upgrade/whats-new.md deleted file mode 100644 index 80f299ec4..000000000 --- a/projects/docs/upgrade/whats-new.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: What's new? ---- - - -You can access all releases changelog with the following links per project: - -- [Koin](https://github.com/InsertKoinIO/koin/releases) -- [Koin Annotations](https://github.com/InsertKoinIO/koin-annotations/releases)