It is time! The stable version of Koin 2.0 has officially been released. 6 months of development, rewriting, API analysis and user feedback. And all this with a real challenge: keep the simplicity of Koin!
1.Startup DSL
The old startKoin()
function was replaced by a DSL startup . Providing initialization for each platform and hiding all options with default parameters is a good quickstart option, but it will lock a lot of development possibilities. Now we need to expand and add new concepts easily, and also make load definitions more efficient.
How do we start Koin 2.0? Still with func startKoin
, but now you need to declare what you will use:
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">fun</span> <span class="token function">main</span> <span class="token punctuation">(</span> <span class="token keyword">vararg</span> args <span class="token operator">:</span> String <span class="token punctuation">)</span> <span class="token punctuation">{</span> startKoin <span class="token punctuation">{</span> <span class="token comment">// use Koin logger</span> <span class="token function">printLogger</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// declare used modules</span> <span class="token function">modules</span> <span class="token punctuation">(</span> appModule <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
For Android, don’t forget to declare your AndroidContext with the androidContext function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">class</span> MainApplication <span class="token operator">:</span> <span class="token function">Application</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">onCreate</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">onCreate</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> startKoin <span class="token punctuation">{</span> <span class="token comment">// Use Koin Android Logger</span> <span class="token function">androidLogger</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// declare Android context</span> <span class="token function">androidContext</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token label symbol">@MainApplication</span> <span class="token punctuation">)</span> <span class="token comment">// declare modules to use</span> <span class="token function">modules</span> <span class="token punctuation">(</span> module1 <span class="token punctuation">,</span> module2 <span class="token operator">..</span> <span class="token punctuation">.</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
2.Better Performances ?
One of the main arguments for upgrading to Koin 2.0, is the new engine performance.
Last year, Rafa Vázquez wrote a benchmarking project to help measure some performances for the DI framework. This helps me very clearly internal review. This benchmark runs a project of 400 definitions.
Here are the benchmarks for Koin 1.0:
Now with Koin 2.0:
Koin has achieved great performance improvements. You should not worry about performance right now ? Contrary to code generate, we need to analyze the components at the start. But this is very fast to proceed right now.
3.Definitions & Modules ?
Koin DSL remains the same! It has been simplified by removing unused features and implying useless complexity. After that, there were no more internal module declarations, weird display rules, and scope API declarations that were completely revised.
The first major change you’ll notice is that we no longer use direct strings to name our components. We use qualifiers instead of named()
functions. This function can take a string or a type to help qualify the definition or scope. This gives us a logical name for a component.
1 2 3 | <span class="token comment">// naming with named("mock") instead of "mock"</span> single <span class="token operator"><</span> MyRepository <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token function">named</span> <span class="token punctuation">(</span> “mock" <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">MyMockRepository</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
It should be simpler to understand now about the DSL (bind) binding operator. Consider that this operator adds a type of secondary constraint to your definition. To make it clearer, let another view it as an additional aspect of your definition. The Koin API has a new bind ()
function to help you retrieve components declared with the bind
operator in your module.
A good example can help understand:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | module <span class="token punctuation">{</span> single <span class="token operator"><</span> ComponentInterface1 <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token function">Default</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> single <span class="token punctuation">{</span> <span class="token function">Component1</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> bind Simple <span class="token punctuation">.</span> ComponentInterface1 <span class="token operator">::</span> <span class="token keyword">class</span> single <span class="token punctuation">{</span> <span class="token function">Component2</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> bind Simple <span class="token punctuation">.</span> ComponentInterface1 <span class="token operator">::</span> <span class="token keyword">class</span> <span class="token punctuation">}</span> <span class="token comment">// resolve Default instance</span> <span class="token keyword">get</span> <span class="token operator"><</span> ComponentInterface1 <span class="token operator">></span> <span class="token comment">// resolve Component1, casted as ComponentInterface1</span> koin <span class="token punctuation">.</span> bind <span class="token operator"><</span> ComponentInterface1 <span class="token punctuation">,</span> Component1 <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// resolve all instances matching ComponentInterface1: Default, Component1 & Component2</span> koin <span class="token punctuation">.</span> getAll <span class="token operator"><</span> ComponentInterface1 <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
4.Loading & unloading modules ♻️
Because it easily loads modules in Koin (via startKoinor loadKoinModules), it is also easy to unload a module. The unloadKoinModules () function eliminates definitions and expressions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token keyword">val</span> coffeeAppModule <span class="token operator">=</span> module <span class="token punctuation">{</span> single <span class="token punctuation">{</span> <span class="token function">CoffeeMaker</span> <span class="token punctuation">(</span> <span class="token keyword">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token keyword">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> single <span class="token operator"><</span> Pump <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token function">Thermosiphon</span> <span class="token punctuation">(</span> <span class="token keyword">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> single <span class="token operator"><</span> Heater <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token function">ElectricHeater</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// starting your module either by startKoin</span> startKoin <span class="token punctuation">{</span> <span class="token function">modules</span> <span class="token punctuation">(</span> coffeeAppModule <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// or after start</span> <span class="token function">loadKoinModules</span> <span class="token punctuation">(</span> coffeeAppModule <span class="token punctuation">)</span> <span class="token comment">// resolve CoffeeMaker</span> <span class="token keyword">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator"><</span> CoffeeMaker <span class="token operator">></span> <span class="token comment">// drop module's definitions & instances when you don't need it anymore</span> <span class="token function">unloadKoinModules</span> <span class="token punctuation">(</span> coffeeAppModule <span class="token punctuation">)</span> <span class="token comment">// Won't resolve CoffeeMaker instance, no more definition </span> <span class="token keyword">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator"><</span> CoffeeMaker <span class="token operator">></span> |
With that, we can handle Koin modules flexibly: load and unload as you like, based on the context of your application. The case of lagging behind works like that, involving single & scrope definitions.
5.Some other new incomings in the Koin APIs ✨
A few small things can help you in special situations, requested by the community. You could try asking for an undefined component or the case might solve the case:
1 2 | <span class="token function">getOrNull</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> & <span class="token function">injectOrNull</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
Another interesting feature, is the ability to add a quick instance. Use the declaration function () to provide an object for Koin. It will declare it as a new single definition for you:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token comment">// Given a Koin application</span> <span class="token keyword">val</span> koin <span class="token operator">=</span> koinApplication <span class="token punctuation">{</span> <span class="token function">printLogger</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token function">modules</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// no definition</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span> koin <span class="token comment">// given an instance</span> <span class="token keyword">val</span> a <span class="token operator">=</span> <span class="token function">ComponentA</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// declare the instance as Single</span> koin <span class="token punctuation">.</span> <span class="token function">declare</span> <span class="token punctuation">(</span> a <span class="token punctuation">)</span> <span class="token comment">// can retrieve our ComponentA instance</span> koin <span class="token punctuation">.</span> get <span class="token operator"><</span> ComponentA <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
6.Koin Isolation ⚙️
The Koin API has been redesigned to allow you to create a local version of Koin. Instead of using the startKoin declaration function to declare your Koin instance into GlobalContext , use the koinApplication function to declare a local Koin instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <span class="token comment">// Local Koin application instance</span> <span class="token keyword">val</span> mylocalKoinInstance <span class="token operator">=</span> koinApplication <span class="token punctuation">{</span> <span class="token comment">// declare used modules</span> <span class="token function">modules</span> <span class="token punctuation">(</span> module <span class="token punctuation">{</span> single <span class="token punctuation">{</span> <span class="token function">ComponentA</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// Custom KoinComponent using mylocalKoinInstance & not the Global context</span> <span class="token keyword">interface</span> CustomKoinComponent <span class="token operator">:</span> KoinComponent <span class="token punctuation">{</span> <span class="token comment">// override the used Koin instance to use mylocalKoinInstance</span> <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">getKoin</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> Koin <span class="token operator">=</span> mylocalKoinInstance <span class="token punctuation">.</span> koin <span class="token punctuation">}</span> <span class="token comment">// An example of component that use mylocalKoinInstance</span> <span class="token keyword">class</span> MyCustomApp <span class="token operator">:</span> CustomKoinComponent <span class="token punctuation">{</span> <span class="token keyword">val</span> a <span class="token operator">:</span> ComponentA <span class="token keyword">by</span> <span class="token function">inject</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
A local / isolated Koin instance is not registered in the Global Context. Obviously, you can directly use the standard KoinComponents extensions. Instead, you must specify the use of your local instance (overriding the getKoin () function from the KoinComponent interface).
7.New Scope API ⚠️
Scope is a context with a fixed period in which an object exists. At the end of the scope, all objects bound within that scope cannot be re-injected. To get a better picture of that, think of a range like a box: a space where you put furniture and throw it when you don iron need it. How do I use the new scoping API? We now declare and use the scope like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | module <span class="token punctuation">{</span> <span class="token comment">// main scope MyComponent definition</span> single <span class="token operator"><</span> MyComponent <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token function">DefaultImpl</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">scope</span> <span class="token punctuation">(</span> <span class="token function">named</span> <span class="token punctuation">(</span> ¨MY_SCOPE¨ <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// MY_SCOPE definition</span> scoped <span class="token operator"><</span> MyComponent <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token function">ScopeImpl</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">val</span> myScopeInstance <span class="token operator">=</span> koin <span class="token punctuation">.</span> <span class="token function">createScope</span> <span class="token punctuation">(</span> <span class="token string">"myScopeId"</span> <span class="token punctuation">,</span> <span class="token function">named</span> <span class="token punctuation">(</span> ¨MY_SCOPE¨ <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">// will give the ScopeImpl instance </span> myScopeInstance <span class="token punctuation">.</span> get <span class="token operator"><</span> MyComponent <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
Finally, in any scope case, you can declare an active component:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | module <span class="token punctuation">{</span> <span class="token comment">// empty Scope definition</span> <span class="token function">scope</span> <span class="token punctuation">(</span> <span class="token function">named</span> <span class="token punctuation">(</span> ¨MY_SCOPE¨ <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// given an instance</span> <span class="token keyword">val</span> a <span class="token operator">=</span> <span class="token function">ComponentA</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// given a scope instance</span> <span class="token keyword">val</span> myScopeInstance <span class="token operator">=</span> koin <span class="token punctuation">.</span> <span class="token function">createScope</span> <span class="token punctuation">(</span> <span class="token string">"myScopeId"</span> <span class="token punctuation">,</span> <span class="token function">named</span> <span class="token punctuation">(</span> ¨MY_SCOPE¨ <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">// will register your instance as a Scoped definition</span> myScopeInstance <span class="token punctuation">.</span> <span class="token function">declare</span> <span class="token punctuation">(</span> a <span class="token punctuation">)</span> <span class="token comment">// will give back the instance</span> myScopeInstance <span class="token punctuation">.</span> get <span class="token operator"><</span> ComponentA <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// drop instances & will loose your ComponentA definition</span> myScopeInstance <span class="token punctuation">.</span> <span class="token function">close</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
8. Load / Unload modules vs Scope API?
With these new features, we have some ability to handle components for a limited time. So, is it using scope API or not? It is more dependent on your use case and how you must manage the creation of those instances. If you need better granularity (timing or definition), the Range API is specific to that
9.Stronger Android support ✅
With such a new Scope API, we can provide you with interesting tools for your Android Activity & Debris. You can easily declare a scope attached to your view and easily retrieve everything from it using the currentScope property (the Koin Times extension for LifecyclOwner components):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | module <span class="token punctuation">{</span> <span class="token comment">// declare a scope for MyActivity</span> <span class="token function">scope</span> <span class="token punctuation">(</span> named <span class="token operator"><</span> MyActivity <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> scoped <span class="token punctuation">{</span> <span class="token function">MyPresenter</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> MyActivity <span class="token operator">:</span> AppCompatActivity <span class="token punctuation">{</span> <span class="token comment">// get presenter from current scope</span> <span class="token keyword">val</span> presenter <span class="token operator">:</span> MyPresenter <span class="token keyword">by</span> currentScope <span class="token punctuation">.</span> <span class="token function">inject</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> MyFragment <span class="token operator">:</span> <span class="token function">Fragment</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">onViewCreated</span> <span class="token punctuation">(</span> <span class="token operator">..</span> <span class="token punctuation">.</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// get Presenter instance from Activity's scope</span> <span class="token keyword">val</span> presenter <span class="token operator">:</span> MyPresenter <span class="token keyword">by</span> lazy <span class="token punctuation">{</span> activity <span class="token operator">?</span> <span class="token punctuation">.</span> currentScope <span class="token punctuation">.</span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
The currentScope property is created when you access and follow the lifecycle of the Android component. It was canceled when receiving the signal ON_DESTROY.
This Android scope API is included in koin-android-scope and koin-android-viewmodel packages (also for AndroidX).
A lot of fixes have been made to the ViewModel section. The global API remains the same, but has been simplified:
- The name attribute of the definition is used as the ViewModel id
- Getting a ViewModel instance for a given class can be done directly with getViewModel and by viewModel.
- ViewModels can be declared within a scope, to help resolve dependencies from this scope
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | module <span class="token punctuation">{</span> viewModel <span class="token punctuation">{</span> <span class="token punctuation">(</span> id <span class="token operator">:</span> String <span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token function">SimpleViewModel</span> <span class="token punctuation">(</span> id <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">viewModel</span> <span class="token punctuation">(</span> <span class="token function">named</span> <span class="token punctuation">(</span> <span class="token string">"vm1"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span> id <span class="token operator">:</span> String <span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token function">SimpleViewModel</span> <span class="token punctuation">(</span> id <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">viewModel</span> <span class="token punctuation">(</span> <span class="token function">named</span> <span class="token punctuation">(</span> <span class="token string">"vm2"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span> id <span class="token operator">:</span> String <span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token function">SimpleViewModel</span> <span class="token punctuation">(</span> id <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> MyActivity <span class="token operator">:</span> <span class="token function">AppCompatActivity</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Get ViewModel by given KCLass</span> <span class="token keyword">val</span> simpleViewModel <span class="token operator">:</span> SimpleViewModel <span class="token keyword">by</span> <span class="token function">viewModel</span> <span class="token punctuation">(</span> clazz <span class="token operator">=</span> SimpleViewModel <span class="token operator">::</span> <span class="token keyword">class</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">parametersOf</span> <span class="token punctuation">(</span> DEFAULT_ID <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// Get ViewModels by name</span> <span class="token keyword">val</span> vm1 <span class="token operator">:</span> SimpleViewModel <span class="token keyword">by</span> <span class="token function">viewModel</span> <span class="token punctuation">(</span> <span class="token function">named</span> <span class="token punctuation">(</span> <span class="token string">"vm1"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">parametersOf</span> <span class="token punctuation">(</span> <span class="token string">"vm1"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">val</span> vm2 <span class="token operator">:</span> SimpleViewModel <span class="token keyword">by</span> <span class="token function">viewModel</span> <span class="token punctuation">(</span> <span class="token function">named</span> <span class="token punctuation">(</span> <span class="token string">"vm2"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">parametersOf</span> <span class="token punctuation">(</span> <span class="token string">"vm2"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Working with ViewModel and scope is now easier:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | module <span class="token punctuation">{</span> <span class="token function">scope</span> <span class="token punctuation">(</span> <span class="token function">named</span> <span class="token punctuation">(</span> <span class="token string">"MY_SCOPE"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> scoped <span class="token punctuation">{</span> <span class="token function">Session</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// retrieve Session dependency from current scope</span> viewModel <span class="token punctuation">{</span> <span class="token function">ViewModeWithScope</span> <span class="token punctuation">(</span> <span class="token keyword">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> MyActivity <span class="token operator">:</span> <span class="token function">AppCompatActivity</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// create scope instance</span> <span class="token keyword">val</span> myScope <span class="token operator">=</span> <span class="token function">getKoin</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">create</span> <span class="token punctuation">(</span> <span class="token string">"myScope"</span> <span class="token punctuation">,</span> <span class="token function">named</span> <span class="token punctuation">(</span> <span class="token string">"MY_SCOPE"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">// give scopeId to your ViewModel instance</span> <span class="token keyword">val</span> myScopeViewModel <span class="token keyword">by</span> myScope <span class="token punctuation">.</span> <span class="token function">viewModel</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
10.Android Experimental Features ✨
Experimental features for Android have been extracted to external packages. You must set it up with the following packages:
1 2 | koin-android-ext & koin-androidx-ext |
These experimental features suggest a DSL version that doesn’t require you to write your constructor function injection:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token keyword">class</span> <span class="token function">CoffeeMaker</span> <span class="token punctuation">(</span> <span class="token keyword">val</span> pump <span class="token operator">:</span> Pump <span class="token punctuation">,</span> <span class="token keyword">val</span> heater <span class="token operator">:</span> Heater <span class="token punctuation">)</span> <span class="token keyword">class</span> <span class="token function">Thermosiphon</span> <span class="token punctuation">(</span> <span class="token keyword">val</span> heater <span class="token operator">:</span> Heater <span class="token punctuation">)</span> <span class="token operator">:</span> Pump <span class="token keyword">class</span> ElectricHeater <span class="token operator">:</span> Heater <span class="token keyword">class</span> <span class="token function">CoffeeMakerViewModel</span> <span class="token punctuation">(</span> <span class="token keyword">val</span> coffeeMaker <span class="token operator">:</span> CoffeeMaker <span class="token punctuation">)</span> <span class="token keyword">val</span> coffeeAppModule <span class="token operator">=</span> module <span class="token punctuation">{</span> single <span class="token operator"><</span> CoffeeMaker <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> singleBy <span class="token operator"><</span> Pump <span class="token punctuation">,</span> Thermosiphon <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> singleBy <span class="token operator"><</span> Heater <span class="token punctuation">,</span> ElectricHeater <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> viewModel <span class="token operator"><</span> CoffeeMakerViewModel <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> CoffeeActivity <span class="token operator">:</span> <span class="token function">AppCompatActivity</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// get your coffee here :)</span> <span class="token keyword">val</span> coffeeMakerViewModel <span class="token operator">:</span> CoffeeMakerViewModel <span class="token keyword">by</span> <span class="token function">viewModel</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |