How To Use Koin As Dependency Injection Framework For Kotlin & Compose Multiplatform - KMP Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
have you ever had a craving for pizza but found yourself lacking the time or ingredients to make it yourself just like Outsourcing the responsibility of baking a pizza to a delivery service the pendency injection allows us to Outsource the responsibility of instantiating an object to a dependency injection framework this way we can simply call the framework and inject the required object in the place where we need it without the tight coupling of no knowing how to create the object in multiple places of our code base coin is one such dependency injection framework that takes care of the incensation process for us with coin we can focus on enjoying our apps Pizza without worrying about the ingredients or how they are prepared in this video we'll see how coin can be used in a cutle multiplatform project with compost multiplatform hi guys my name is S I hope you're doing well and I welcome you to a new video the peny injection is probably one of the most popular design principles in the modern software development world and therefore also very relevant when it comes to developing a mobile app with cotton multiplatform by using dependency injection just like we are no longer dependent on the baking process of a pizza and all the required ingredients we can receive our or inject any pizza from our delivery service to our house door we don't care about its baking process so whether it's just warmed up in the microwave or actually baked from a pizza chef let's even go a step further let's say we are that hungry that we don't even care if it's a pizza or a hot dog the provided food just have to be eatable that way we can rely on the abstraction of food and it's solely purpose of being eatable just like from a software object which we expect certain functionalities without actually carrying about its implementation logic as long as it fulfills the contract of a specific type like an interface staying in the software world the design principle of dependency injection allows us to develop testable code by simply swapping out the actual implementation we use for our runnable app code with a testable implementation or a mocked version when writing our unit test but not only the testability improves our code will be automatically be way more maintainable when instantiation of our dependencies happens in a single place of our code base and an object no longer needs to change just because a small part in the intiation logic of the dependency changes coin is a dependency injection framework that can act as our pizza delivery service it is coton multiplatform and composed multiplatform compatible very easy to set up and provides a very simple API in form of a coton DSL that allows us to declare any implementation Logic for types that can then be injected as dependencies in almost any place of our codebase but that's not all if you don't like manually declaring your types you can even use coin's own KP plugin to automatically generate those definitions via annotations we start with how to set up coin for your cotland multiplatform project with compos multiplatform we will see how we can Define our types that we want to inject manually via cotton DSL and afterward how to do the same with the KP plugin and how to inject classes not only in regular cutland but also our compos code so let's talk no further and get right into it so before we start make sure that you check out the compos multiplatform Android and iOS template project just like we saw it in the previous videos additionally I checked in the GitHub project I used in this tutorial video here so you can also look up some dependencies and so on there no need of manually writing all the stuff just copy it and you're good to go so the first thing we need to do when introducing coin in a new cotton multiplatform project is to add the required dependencies and because we're in a composed multiplatform project most of the part will happen in the common main module so here in Android Studio make sure that you go to the build Gradle kts file of your shat module let's scroll down and here you can see we added some coin dependencies so the first one is the coin bom or bill of materials inside this bill of materials there are compatible versions declared so if you add another coin artifact here because there already like 10 or 12 artifacts it will select the respective compatible version whenever you need to overwrite that you can simply add your respective um Alpha version or whatever here afterward let's go into the Android app module and here in the build Creator file we also add the same coin bom but this time not with the coin compos dependency but with coin Android for the raw coin DL usage that's already it for setting up our KMP project next let's see how coin Works in practice so how can we actually declare a dependency let's start by declaring a new F structure here so let's say we call it um right do cotland tutorial. shared and let's put in our code here make it a little bit bigger let's start by declaring two new classes Class A and Class B so and let's say Class B depends on Class A somehow we can use two different approaches here one is feeld injection and the other Constructor injection let's quickly see how we can use feeld injection so to do that here in class B we need to implement the coin component and let's say we have a field here that is called Class A and now to inject it we simply say here inject and this inject comes now from the coin component and as a type we say we want to have class A and that is already it for the feet injection but what is the problem here with this approach in this case it's not that easy to overwrite this dependency or this implementation with a mocked implementation or a test implementation for a unit test so so the better approach is to use the Constructor injection so we can instead simply Define the class A here in the Constructor now we can also again remove the coin component and are done at this point but how does coino know how to provide the class A for class B and finally how to provide Class B somewhere when we want to inject it in our real codebase for that coin used the concept called modules in those modules we Define our our um type definitions and coin will do the rest fors let's first create a new file and we call it shared module and here we simply declare new variable let's say share module and then we can use see cotlin DSL from coin now inside this um scope here we can Define our types so in our case we want to have a class A and A Class B let's start by declaring Class A as a Singleton so whenever it gets called the same instance should be returned for that we can use the single keyword so here because Class A has no further dependencies we can simply instantiate it VI The Constructor call here when for the first time this class A will be required it will be instantiated and provided to the respective classes when another class requires dep pendency again the cach will return the same instance we had before this happens only at the first time it will be called how can we for example uh created from the app start for that we can provide here a parameter created at start should be true so now if we start our app with coin a single instance will be created for class A okay great now we have our definition for class A let's proceed with class B Class B should always create a new instance so for that case we can use the factory keyword and if we now say here Class B we can or we need to provide the respective dependency for class A how can we do that for class A we can simply say get and get also comes from coin when the dependency will be resolved at runtime it will automatically see Class A is required and because it's the only instance here that is um available it will simply provides Class A okay that was a simple example but let's say we have two additional classes so there's also a Class C and we have also an interface which is sample interface now Class A implements this sample interface as well as Class C and now Class B should no longer depend on Class A but on Sample interface so if we now go back here to the shat module we also need to provide a type for Class C so I now also both of these penes here should be uh for the sample interface and now you might already see the problem here we have two definitions that both provide the sample interface which of those should coin take in this point for that we can use a so-called qualifier and let's say that we want here a qualifier and we can also provide here an enum but for this case let's say we want simply a name and it's ABC when providing the definition here for let's say Class C we can also provide such a qualifi Fire by doing that coin will at run time know which of those types it should provide okay that was quite okay to Define I would say but coin also provides other methods for defining those definitions let's see how Constructor DL for example works for this class C definition here we now say instead sample interface once again and then we Define the class C here in this Lambda and because we also want to provide some options we can simply say with options and have another Lambda in which we now can say created at start and also named and this named now also contains a label so once again ABC and we can remove the previous declaration as you probably know it in the curse of developing a mobile app those definitions change quite often so instead of um hardwired declaring those things here we can also to use another approach and let's say instead of um declaring here the class A in that way and maybe in the future there also will be some more U dependencies that we need to provide in the Constructor we can instead say single off and now we just need to provide a function reference to the Constructor of Class A so let's say here Class A and as you can see we are already done what if we would need to have here um just as an example um a ASD as a parameter if we go back you can see that we need to provide a string here but in the single off we don't how is that that is because single off has multiple overloads of up to let's see uh 22 parameters we can provide in the Constructor without having to touch this declaration here so as you can see there are multiple ways with coton DSL alone how you can declare those definitions and if we also want to have here creit at start we can simply once again say here in the Lambda block created at start and would achieve the same as the sample above here so let's also remove that now that we saw how to declare those modules let's see how we can actually use coin in our application so now that we saw the module approach how to define our dependencies or definitions how can we actually use them in our app code for that we first need to start up coin at the point of app initialization and in that point we also need to provide all the modules we need for our app for Android that's quite easy because we can make use of the Native tool set so let's quickly see how that works for the Android part that's quite easy as we earlier did we introduced some dependencies in the Android module and now we can also access them so the first thing we need to do is to create a new application and implement the Android application here then go to your Android manifest and also declare the application here in the application block so it will be used instead of the default one as you can see we have here the start coin we provide an Android context so you can also use injection of the Android context if you have some specific Android classes we use here the Android logger to lock some KSP stuff and then we need to provide all modules and we can simply do that by saying here modules and you can see there are three overloads but because we only have one we can simply say here shared module and for the Android part that's already it to use coin in your app IOS however we have no native tool set to start coin but we can use the concept of cuton multiplatform so let's go into the iOS main module here and inside that we Define a new function and say init coin and here because we are on the um shap module we can now also use the dependency we declared for the common main module and that is now also start coin and let's here simply say U modules once again share and I realized it should be shared not share and now we also fine for the KP part and now we also need to call this part here when starting up the IOS app so for that let's go into the IOS app folder IOS app and then inside the IOS app switch fire so if we now switch to the iOS project in xcode also initialize coin here so we can do that by first importing here the shat module and then we say here in it and then we can access the main iOS KT which is the shed file we earlier provided and then let's say do init coin and by that let's quickly try out if the app start up oh and as we see the app crashes but why is that because we earlier defined the string in the class A here but because there is no respective definition that coin can use and we also said start coin at the initialization of the app the app simply crashes so that is one drawback with the raw coton DSL because you don't know at compile time if all required dependencies are provided we now um remove this parameter here and then go back to the EXO project and now we rerun the whole thing you can see that the app started up and we also have our hello coin here okay now we saw how we can use coin DSL for declaring our definitions but how to do the same using the coin KSP compiler I earlier talked about for that let's go back to the build grader file to introduce some new dependencies because the plugin is a KSP plugin we also need to enable KP for our KP project first let's go into the Gradle properties file and here add a new dependency if you are also on cotland 1.9.21 then you can also use this version or a newer one and next go to the settings. cre kts and here introduce the KSP version for the project by declaring here um an ID com. google.de tools. KP and set your respective version so everywhere in our project we use the KSP plugin the same version will be used then the first thing we want to introduce the KSP plug-in is once again our shared module and here you can simply use the ID now because we earlier provided the respective version in the settings. grader file it will use the correct version then go down to the source sets and here we want to provide a source directory to tell the common main uh module where it can find the generated files so in this case KB metadata Comm Main cutland and then we go further down to the dependency section once again and make sure that you introduce this dependency here so that in our shat code we can also use the annotations from the coin annotations artifact then it gets a little bit trickier now create a new dependencies block and use the following statement here you don't need to write all the stuff by yourself I also got it from the um insert coin IO hello hello KMP sample project from coin so you can either um it from there or use my GitHub repository I put down in the YouTube description and by using those grader task here or configurations we make sure that the KSP process first compiles and then the actual cotlon compile process after that cryptic part also go to the um Android module once again and here inside the build grader kts we also need to provide um one the co annotation implementation and then with the KSP keyword uh also the coin KSP compiler and also don't miss to add the KSP plugin to the plugin section here once again you don't need to follow it just copy it from the GitHub repository okay now that we have that in place let's see how we can use annotations instead of manually declaring our definitions for that let's go back to our shat module now in this chat module let's say we no longer want to declare all this things manually but do the same with annotations so for class A we want it to be a Singleton so we go to class A and simply say here add single next for the class C it's the same and we also said that class C has this qualifier and the equivalent is here just to say at named again it's ABC and the same also goes for class B so here we also want to have Factory and and now we can simply say here in front of this parameter named ABC and now if we build our app the default Behavior will be that all annotated classes will belong to a so-called default module because in general it's a good practice to have um yeah encaptured modules let's also once again reuse our Shar module here but instead of this declaration let's slightly adapted class called shared module and here we add a an annotation where which says um module and we also say your component scan so if you would like you could also provide here specific package which this module should get this components from in this case we say um use all of those packages here can optimize this quickly rebuild and now you can already see that we have some problems here because of course the variable is now gone so we can replace it with shared module and then we call here mod module which is an extension function from the generated code so the same goes for the iOS part or the uh multiplatform part here so we also place with shared module do module so fix this import and now if we rerun the Android app as you can see everything works as expected okay great now we saw how we can use the manual declaration The annotation based declaration but how to use use those dependencies actually in our compost code because at the end we're here because of our compos multiplatform project so let's say we have our class B this class should also do something so calculate uh something maybe 2x3 and now let's see how we can use that in our compost code so go to the app KT file and to use this class B now in our code let's do a quick refactoring so we put this into app content and now once again you to add the composable notation and what we need to now to do is that we need to take the coin context we started from Android and iOS and use for our compos code so we can simply say coin context and inside of that we launch our or put in our app content composable here and now let's use the class B here so we say simply um Class B type is also Class B and then we can say coin inject and the only thing this composable function here does is to resolve our respective dependency so in our case this class P from our coin context so let's quickly um use here column instead let me say here fil Max with we add a small text sample text and then let's say here sample text equals remember and for one time the first composition we uh you calculate something cast it to a string and let's say I don't know um we also say result and let's simply show here the text of course that should then be sample text and let's quickly also dab that here and now let's start the app okay great let's click on the button and as you can see we have result six here so with without knowing how this actually is implemented we can just say here coin inject and we receive our dependency and we can simply call it and by that you should have a brief overview of the coin dependency injection framework with a KP project and compost mplatform of course there are also other options and functionalities that coin provides but I think by now you should be able to implement dependency injection framework into your own project are there also other depend injection Frameworks you already heard about that are multiplatform compatible if so let me know in the comments I hope you had some takeaways like the video subscribe to my YouTube channel activate the notification Bell and I hope to see you soon
Info
Channel: Yanneck Reiß
Views: 5,262
Rating: undefined out of 5
Keywords: Kotlin, Compose Multiplatform, Voyager Library, Mobile App Development, Navigation Solutions, Kotlin Programming, Multiplatform Mobile, Kotlin Tutorials, Compose Navigation, App Development Guide, Software Development, Cross Platform, Voyager Navigation, Kotlin Multiplatform Mobile, KMM, Compose Framework, Voyager for Kotlin, Kotlin Jetpack Compose, Mobile Software Development, Kotlin App Navigation, Kotlin Compose App, iOS Development, Android Development
Id: A6Ksf3ylEsM
Channel Id: undefined
Length: 23min 12sec (1392 seconds)
Published: Sun Dec 24 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.