Dependency Injection For Kotlin apps with Koin - Arnaud Giuliani at Kotlin Day 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] thank you being here for Saturday for cooking day we talked about dependency injection as a first topic then hope you take a coffee just to present myself I'm under Giuliani as you may hear i'm french i'm making some mobile and stuff and i need of the coin project and then we will talk about dependency injection and cutting and before diving into any source code of stuff we start with the first embarrassing question and this is the question that people ask me a few few months ago few week a few year ago say why why guy are you crazy enough to try to start another framework we hurried a half dozen of that and to give you an answer best is to go back in 2016 and 2016 we have something that it was huge in the community that is was cutting the first table version and if you remember the website it was production ready and because it was production ready i put it everywhere I could then in all my applications and stuff you could ask my ex colleagues to about that but yeah and when you unlock cut lean and you begin to write stuff you feel yeah I have really amazing Steve and I feel like a superior but then we have still lots of tools that are driven by Java and lots of tools that are very good but then that means that it's kind of av syntax once you have begin to write cutting you see everything of that that is a bit a bit yeah has a bit boring then let's try something else let's try something else and for the penance ejection that mean that this is the core things that you need to build your your application even at the beginning you can even don't use any GI framework it's kind of fun because you have object classes functions generics lazy delegates and you can still find many article and Antonette about about that writing your application without an idea I just manual way you see that it's very fun but you will see that after a few days picking a bit yeah then for me I was looking for simple d.i.y solution and simple for me is really bleep one of the core things for me in my daily like daily my daily daily life as a developers simplicity has everything has to be simple and when you look at the market tools for especially here and read the repent yeah no that's not for me here because yeah I want something directly focused on my needs I want something directly not driven too much by theory because I don't want to read books on theory and I don't want to understand the theory to understand the tools and stuff I want something really that I can read and understand because I don't want to read documentation and also because I want to be able to write something simply just behind that and let's take a sample application just to see that together and the best I would say this is just an application like the coffee maker app and many people and in the Android community know that about this is one of the best sample app that you can have on dagger repository or something then yes what is this happen this app is just a coffee maker class okay and we want to brew the coffee and then what we want to do is that we will use components and then inject them by interface just to demonstrate that we can inject without the implementation you use directly the components by the interface not by the implementation then we have a pump and we have a heater for that what we want is that all coffeemaker class is using a pump and a heater by the interface and then we will inject the implementation classes beyond that directly and the thermo siphon will pump hot water then it will be linked to the heater directly then the coffeemaker will build a coffee house for hot water will heat the water and then we get the water and the coffee yeah and you will see the here we will see pure cotton pure cotton and just only class and interface just things that is very the most simple thing that you could write in cotton and we can write we can begin with the ether that is the most complex interface yeah three functions on off is hot and then the implementation behind that is not so much complex then we just want to say we are making the water heating Han we just have a variable here half and then we can say if the water is hot you see not very super complex here and we have a thermo siphon how we can make this thermo siphon again very simple interface here we just have a function and how we do that in terms of cutting here what we do is that we write a class thermo siphon we use the constructor to use directly the heater property and then we use a constructor injection here injection that mean we use we use the constructor here and then we can use the heater directly in how in your function to pub then we have the the pump we have the heater and then we will have the coffee maker class that then use a pump and the heater in the constructor and then brew the coffee that mean that we are making all the process and we are printing the shiny ASCII hard stuff but that's not all we need we need something else we need an application to run this and then what you need here is that it's an external class that will horan that and then we need something that is bootstrapping this property outside of the application and run it okay just something that is running this application this is the main question how you assume that how you make your application delegate the the assembling of your components somewhere else and then you ask this component to give you the instance that you want if you write those classes directly without body okay we take just the classes like that if you write by hand just by end you will write like that like I have a hitter I have a pant and we have a coffee maker they're super easy but what I want is that I want something to add me get my coffee maker in instance something that is making the instantiation of electric heater demos - making the link between that and then getting give me the these instances okay as a coffee maker here okay and then here the intuition was that we have definitions we have classes that we can instantiate and then with cutting we can quickly make make it as a function to build that and finally you see that week we can make a link between this and this that mean but might as thermo siphon class need just this electric it a function somewhere and then in terms of DSL and meaning perhaps we can do something like that and this is how the idea of coin just just raised that what what is coin then it's just a cocaine DSL a lightweight container that means just think in terms of a little thing that is running your functions to run your graph your definitions and we need also a very simple API to let you understand quickly and in an integrative way to use all of this and then pure courtly no no particular magic the idea was to not read them to will because there is already interesting frameworks into interesting solution yeah you what to say can we do without all of that and to play with pure cotton you can use a greater definition here that means you can use the coin core package directly in the calibration and then you can begin to use directly in dependency injection in any kind of cutting application that means that you have to declare your definition first then we have a module keyword here that is defining the space where you want to have your definitions and each definition will be either single or Factory that means something that is the sign in singleton or something a factory something that will be recreated each time you have for it mainly this is the main usage of what we wait expect from this kind of stuff and here you see that we have brackets with a lambda expression and this lambda expression is a function to help you build what you want here and that's it that's it you have made your your expression to declare something that you want to build because it's just a function to create something and just in signal to a factory way let's go with coffee maker application how we can do that we can just simply declare a module okay just a value here available and what we can do is we say okay we want to declare this electric heater what we can do is say singer of electric heater we are directly using the we are calling the constructor of the class directly here you see and finally as we don't remake kind of magic or introspection you have to be explicit in kind of in in your declaration that mean that if you want to find this definition with the heater tied you have to say to coin it will be this type okay this will be this definition but you want to find it by heater interface okay as can we find it by electric heater but this is not what we want but then this is the only stuff that you have to keep in mind is that you say single the hitter of hitter and then you have electric heater let's go for a thermo siphon and thermosyphon will be kind of the same as we have a pump and then we just say we have a demo siphon but here you will have a problem because this is purely cutting this is in your code this is compiling you stuff then your compiler will say there's something wrong why is something missing here and what you have to just say say yeah get get it for me please and finally because cotton is smart enough to get the time for you then you just have to write get and that's it you make the link between your definitions and then you have declare to the finish to two components here and you can declare the third one that is the coffeemaker we don't need any particular interface here we can instantiate it directly and then we can say okay result that to the two dependencies here and that's it three lines you have your components very simple to read and I believe that you can rewrite anything behind it think that also you can split the stuff split the decoration if you want like that there is no particular rule because cone is purely runtime that means that you don't have static tooling perhaps yet to help you understand how your graph or your definitions are mapping in your IDE but you have tools to verify it just after that like like running some tests and stuff like that but we will take on that later okay you have seen how we make the definition one of the other concept about coin is the coin component concept that means that for us this is a class that is a particular class is a class that is allowed to use the coin container because we don't want to allow you to access to the coin container in a wild way that means from anywhere making static access to coin Oh what we want is that we want to provide you an interface marker for us because we want to identify any kind of link to the coin API for you and for us it's a good way to give you the extensions directly because then you have really a non-tree point in your class to say this will have access to coin you have components that are declaring corn and you have components that are using those coin definitions then the coin component or the coin component interface allow you to get and retrieve those condos interface those definitions and for us this is the main way to bootstrap any kind of runtime from Android to cater to any kind of other environment to work with and that's it that mean that what does it mean that mean that for my class that want to run my definitions in pure Kirkland I would just say I use coin component interface and I have my by inject ready there that means that I just write by inject to retrieve my definition and that's it you have it you're just define your stuff and then you just write by inject and that's it what you need to know now is that you need to start coins somewhere then what we do is that once everything is written down then in your new start point here just a main function classic one we say star coin that will open start a little DSL to describe what you want to run here but mainly you will just have made this main function that mean that you say start corn with my module and that's it you have to start coin and that's it you are running it if you have several module you will run that and after that you are free to learn your stuff and you got your coffee then it was just purely codling dependency injection we can see in other platform like Android and Kaito and also other stuff around and we will see many features around coin with that but let's start with the Android then because the pain in the community around coding community 95% of the con users are Android developers because of the existing solution are very heavy and how to scale because of compilation time compilation generation and everything then then we bring something for you that means that the problem with Android that you can't create directly an activity or fragment or service by n you have to ask Android to launch the stuff for you and then that means that you can't just launch those classes by hand what you have to do is to subscribe in the life cycle then coin offer you extensions for activity fragment and services directly out of the box and make them as a coin component ok and then what do you have to do is that you just have these Gradle the dependency ok coin Android and what you do is that you start your application here what you have to do is just start coin in your main entry application have you can have an Android logger if you want to log every coin stuff in a log cat and have you have to specify your Android context also then you can say this is my current context and you will be able to inject it elsewhere and then that's it you have your definition here this is the coffee maker module and if I want to retrieve my coffee maker or any describe dependency as well then in my activity what I will write is that I say coffee maker bind yet it's very simple and very straight of the box to get the Android context don't forget to have this in your start point description to have your context and then when you dis the definition in constructor you can use the Android context directly and then when you when you dis you define your that your your component you just say Android context or even get that mean that this is to function that only you to resolve that Android context is more to resolve directly the Android context type directly one of the usual case that we have is when people are still making like architecture like MVP or need presenter around activity or kind of transient components around your activity fragments etc then the easiest way to declare it with a coin is that you just declare a factory about that that mean that I have a presenter class that is just using my coffeemaker ok and what I have to do is just declare it as a factory because then I will declare it in my activity then I will say I need my presenter then I say by inject and the thing is it will ask for a new instance but then I don't have to react or something it will all the instance for the activity cycle and then if the activity drop the the present instance drop but then we don't have to carry more about that if you want to go in a deeper in a deeper solution best is to be is to use the Android architecture components and the coin has been one of the first framework to be ready about that that means that is one of the first to get you to put to to app you use the view models directly for you then there is a Android Android X you model package do for you that means that it's bringing for you all the view model features and then again it brings for you extensions for T Android view model directly and other feature on that but mainly once you have declared this Gradle dependency is that you can use in your view model you can use the constructor injection that mean that you can open your constructor write anything you want and when you declare the module here what you have to to declare is you declare a view model this is a special keyword for the coin definition there and then you can you just say I have my view model here and I resolve my stuff just a new keyword that is special one not hard to remember because this is just view model key one and then one you once you want to retrieve this view model instance what you have to do is not declare it your property by inject but by view model because this is a special injecting instance coin has to pass it to your Android view model Factory will make it for you you don't have to describe any Factory we make it for you this is this is the point for coil we are making the dirty code for you and just focus on what you have to do okay and that's it this is also working for your fragment that means that you have the same here you will have an instance dedicated for your fragment one of the really interesting feature is that just by saying by shared view model you are reusing an instance of your model between your activity and your fragment that means that you can share easily your view model between your activity your fragment and then you don't have to imagine a imaginate any kind of hard communication between your present notify the staff have really hot stuff around them but then that means that just by share view model you can have activity and fragment communicate easily and then have the same instance of your model for the people that are that have looked about this new Android stuff and read X extensions at Google i/o this year we had they have introduced the bundle state that means that your view model can be can receive any kind of state directly the a bundle state that means that it received an object that is called the state that you save in your activity and this is purely still in alpha this is in current development and then you can find in in the next package that is in 2 1 0 alpha something and then this is in the Android X package and what you want to do here is that in your constructor you will use a safe State handle this is the the API from Google let's say that we can pass you the state of your application directly and if you follow the Google API you have to make everything by hand what could what kind proposed here is that you just describe it in your constructor okay and then what you have to do is when you declare a view model in your module you just pass directly as in the function you just pass your state okay and you will use it in your view model and in your class the thing is you will see that you with you will see by view model and you open a lambda about parameters of bundle that mean that we will will take back on the parameters of functions after that but you can pass directly your state and your bundle directly with two lines directly in your view model declaration about the fragment they open also this year Injection about fragment that means that they begin to open the API to allow you to make real constructor injection but is because this is still very painful to declare things in android but they begin to open the ability to have factory then if you continue to follow the google domain google api you have to write factory everywhere what propose this package here that is also in alpha is that you just write your fragment with constructor directly and what you have to do is to declare a new module fragment okay very easy enough also and then in your activity on your own create stuff you just have to use the current fragment factory that will make the for the for you and then you on create stuff and when you have to instantiate your fragment you just use the Google API that is using the class definition directly and then that's it you don't have to write your factory again we write the factory for you we make the the linking directly for you and then this is fairly straightforward let's talk about kato okay because guitar is a little async programming framework for from jetbrains and we have you have the good side from the web here and if you want to use coin with cater you mainly you have to use these kato package and SL 4G package also that means that we bring for you SL for geeloger directly for coin that will be compatible with the runtime of Kaito let's start with the entry point here that this is the way that you can start an embedded server with Kaito you just say we are using Nettie and this you will start my stuff here and you will have an extension function to say this is my main entry point I want some default stuff like install errors coloring etc and you are decrying your routing okay and then if you want the dependency injection here what you have to do is to say I'm in stunning coin directly because coin is a Kaito feature directly out of the box and then you can say ok let's use a logger let's use a modules and then you have access to your instance everywhere just by saying give me my coffeemaker instance by inject you can retrieve it directly here in your routing stuff and then you can use it everywhere fair enough it's in your routing DSL and then coin off for extension for Kaito in all these applications route and routing classes and make him as a coin component also you see that the concepts are really straight simple the DSL the coin compo and once you have that you can play with our definition everywhere the other thing that can be interesting is that you can even use some kind of reflective declaration that mean that if you don't want to play with functions to declare things and don't want to use the get get in your constructor we can you can do that because you aren't jvm and then you are not restricted by resources and then you can say single of this type or single by type you want to find any type of implementation and we are making the the injection for you directly you can even start stuff at you can start definition that means that coin will create the instance for you at at start okay kaito and read one of the other stuff that is very important is that you can test what he you are writing fairly easily with coin and this is very important because you have to be able to test and run integration testing you need testing unique testing will be very easy because we are pushing for constructor injection then you don't need any DI framework to test your stuff but you can use some of testing tool to app you go a bit far a bit further we are rewriting that because we want to extract the API that is currently using mojito and we want to offer the people the possibility to use either mojito either mark a any kind of other mocking framework and not push you a straight way to to to use mocking but the first tool that you have to take care when you are using coin is that you are you can check your graft working and that means that you can have your application you are making developing with coin and with just a J unit tests you can say ok start my application this is my module then please check them that means that if you keep it in your CI or even you can run it regularly when you have adapt in your definitions you can say this is a an easy way to check what you have and then you have the mojito part 2 app you mark on the fly everything that you want to test that mean that it avoid you to rewrite definitions just because you are mocking this out these parts of your application that mean that you in a J unit start coil use a coin test interface and then you can inject definitions directly in your class okay and fairly you can declare mock that means that with this API you say okay in this test this will replace my definitions with the Mach one and then you will be able to use directly on your instance here on the heater instance you will use the mockito api only kind of mock api you want here but this is a mock instance and you don't have to rewrite things this is directly ready out of the box to let you mock on the fly your your definitions and then you can run your test and verify your result this is important files because this is in testing test is important to give you your definitions and your instances but also to let you mark and bootstrap some part of your of your application right now okay we have covered main of the getting started topic that means either Johann Android developer or coding developer you can pick some of the topics but the main idea is still remain the same that you are writing modules okay running the stuff and perhaps you need some extensions to bootstrap those extensions and then after that you can run everything you want with that I would like to share many many stuff but I don't have the time today but I will talk about other little topics together for a time that is remaining and just to share about something is that the second version stable version of coin has been released in June and then it is important to highlight something that is since the first version people really like this simple yes that mean that you have just four key words to remind to keep in mind modules in your factory get and you will write mostly of your most of your application with that and people like that that mean that you can you don't read documentation you just read a snippet and you say okay yeah get single stuff etc yeah fine and the second one is the the API is quite pragmatic you can find the inject or get mostly everywhere and mostly in the most used classes then this is very accessible and yeah you too to begin this is the first stuff that you need it was important for us to release the second version because mainly the first engine was white if slow and people from some people from the community begin to make some benchmark because the target was to say okay for big application like for Android definitions it begin to be very slow because we were very we were a very based on functions and then resolution and functions in kourtney's can be very a bit heavy in terms of performance then we have to take back to something that are more performant for us and we have to rethink about the graph and the definitions and everything we are doing and then we have something that is very performant but I would take a better sample for you that I take the coffee maker module okay I tried to benchmark just the start the first call to the to the coffee maker app and then a second one that means that the second one will take the cached instance and I took a very well know tool from the market that he's making a code generation called dagger and then I compare the performance just in the heart resolution and you will see that finally in terms of resolution framework is kind of really close to the same performance and the only thing that you have to take care is that finally even for hundreds of definitely we will have the same possibility to go as fast as this kind of generated solution the only thing is that at startup we have to read your stuff then coin just will show you that coin is fast enough to let you build very good application and if you have to load many definitions like 400 we are making benchmark to let you understand how to understand how we can try to load that very fastly but one of the of the advice here is that if you want to speed up your your startup the your startup time you can even split your module start you can load your modules when you load it you don't have to load everything and start you can do everything is lazy by definition and then I think you can you can build up really serious application I mean that I'm working with lots of client and I think with many hundreds of definitions you don't even notice about any kind of problem then it's up to you to understand the performance of your application and where you need that if you want to compare also some kind of all the the benchmark and everything you want you have a github project here you can we are comparing thermosyphon and we are comparing the benchmark and this benchmark stuff about slow is comparing codeine diagur and manual stuff and trying to understand what is the cost of the start and the resolution if you want a changelog about coin to zero to understand all the new features from this year you can go to ready for coin bitly dot ready for coin and then you will get lots of stuff i would like to highlight something about the container and perhaps you are you have heard about coin about these stuff I think if you throw those keywords on Twitter with coin you can make the Internet get flames directly then be careful but yeah dependency injection service locator I would say that you are using both and I will explain why because when you are working with your classes like that and you are the current definition is that finally we are making constructor injection and your class do not depend in any way about current and then this class these classes are built by the coin container and then you are also using a functional approach to go to build that that means that single of lambda this is a way to give you a function to build your stuff directly and then this is dependency injection in the other way when you have that that means that you have a host application that is not created by coin and then you are using the coin API actively to retrieve your dependency then you are using service locator ok you see the difference Y we are using the tool then but then is the locator bad stuff to give you an answer I will just compare two stuff then service locator here ok we have directly delegate the well know delegate by inject and you have the setter injection here that you can find in other framework that allow you to make some something else that construct an injection and what's the difference here is that here in the service locator you are actively asking on the property to inject your staff and in the setter injection you are asking the DI to inject your property directly kind of not far but this is not the same and you see perhaps the the difference but yeah finally think think the best for you I'd I'm not here to force you think in a certain way I would just say that 80% of your con usage will be configuration after that we just use some extension to retweet that and I was just quote Martine follow about that that says finally located events injection and is this is extracted from is well no dependency injection article and Edina says the main the main things the important thing is not dependency injection or service locator the main things is about separating configuration from the usage let's talk a bit more about functional and why I'll talk about functional dependency injection here because we are making functions and we are from making functions regarding your context that mean that if I open the source code when you are writing something like that you are making a function that is using your Scott in your space where you have your instance and then with resolving that with your parameter that we can inject with your definition then this is a function that means that we can interact with rain twisting elements with your definitions and then a very good interesting sample about that is how we can easily inject parameter on the flight with those functions that means that here I have a presenter or something that is factory created and test will be to have this ID property in a constructor and not to have to set it afterward by just using a set ID function or something like that how can I do that with coin is very easy you have to use these parentheses declaration of parameters just to say that in your injection function you will say okay I have an ID and I will use it in my in my in my my definition yeah that's fine and then I was saying before that we were checking about these parameters of stuff but that mean that if you want to inject inject parameter you have to give them and here we open a lambda expression to say we have parameters of something and then it goes directly to your definition and here the interest is that your parameters of is also lazy evaluating that means that you can evaluate all those parameters in the first time and then evaluates your present in a second time to have your stuff and this is very powerful because it's super easy to write and then inject stuff that you need view model is the same as you can just say we have an ID and you have say you have also the safe state bundle object that you can pass and then we can just inject this parameter directly out of that for the safe state parameter bundle we are detecting that you see it is a safe state bundle type then we are making the right factory for you on the fly we are making the article for you just focus on your code not stuff that are painful for you if we want to make some reflection I don't like that I would like to give a thrown ion meta arrow meta or something that will be better to make something because here if we want to make reflection and people would like to get rid of the get get get stuff in the constructor yeah you can't use the functional approach about that then this is an experimental external package two letters understand some of the feature but the idea is to say okay if you don't want to write functions and you want earth to make the constructor injection for you you can write something like that but then you can't pass any more parameters or you can you can't have the magic of using the the functions in your declaration anymore but it's yeah I understand that this a bit more easier to to declare and this will is available directly for all the JVM pure JVM platforms directly and for Android you can also have that in the Android and unreal ex external package and you can do the same with you model that means that you can say you can just write something like that you don't have to forget something is that behind that you have to take your program rules because you have to keep your constructor open then okay and also you will notice that finally if we are making reflection for you it will be for time to 10 times faster slower then if you were writing that in a purely functional functional way no magic if we are making the stuff for you there is always a cost for that but then this is carry easy in terms of cost regarding the fact of just writing functions up to you to use the right sub for you and then you can get you can have this just say ok let's go get home and convert all my application to coin but this was my my last word for previous session but finally if I look at every of my successful story no you can't refactor all your application directly because you can't go to your business and say hey guys I just need three three weeks to refactor all the application for what just to make coin and say no no and this is the top one problem of the community that we have a user survey that is running from September and the first problem of the people is that once they have a very hard di solution once they have already made everything with that it's a bit late it's very hard to get out of the current solution and mirskiy people what this is what are using the other solution that has been used by con con users I've also used dagger spring a bit of things but fairly you see that most of people are using dagger here and then finally what if what if finally you could just run something out of your application don't break anything but finally run something in a separate module easily and because finally if you have a coin container you just say start coin load coin modules on the fly you can have your definitions and you can unload them easily fairly enough and finally this is interesting because you can begin to open something that is more kind of making dynamic modules approach that means that you can load your definitions easily and compose with them but just to explain you know stuff is that if you have for example a financial application classic one with opening wallet profile transaction and what we can do is that we can change some of the module directly to say ok we just start a new module a new activity that is directly using coin we can change one module by another switch diversion add new feature or even say we switch this on boring part just to use this part of the animal on the onboarding jerky with coin and this is very it is an interesting approach because it's not a braking approach you don't have to refactor you can start new things in a new module with coin and then you can start to to have fun again with your with your new modules but then you have to prepare in many components you have to have some kind of registry plug-in architecture and I think this will be the next type of another talk about coin and to show you how you can build new application you can inject coin in any kind of application without breaking any things yeah what's next in coin then this is the world the current world map that I published in in June and we have fairly lots of stuff that are on the table and I would say that for now fifty to sixty percent of the work has been done by the community and this is good just some tips and tricks for people that don't look that want to start with coin that you can start coin in five minutes you can you have some getting started project quickly that means you go to start dot insert coin dot IO and you have you can start coin with Android and with Java you model Kate o Corinne you can you can download a github sample project and you can play without directly we have also a doc dot insert coin dot IO for all the documentation and one of my advice is that yeah added step-by-step make it very small keep it simple don't forget to check your modules and yeah this is the module of coin I believe is keep things simple please and if anything goes wrong you can go on Stack Overflow github slack we are we you have a coin channel on the Copeland slack and then you can find us easily even open something on Stack Overflow and or github you can follow the project on Twitter major and the best thing is that we need your feedback because this is not just the creation from one guy this is just ideas and people that share ideas and make thing things better together and this is made by a small community and yeah this is good thanks thanks for them some takeaway for you the stable version is two one 201 and the next one is 2 1 0 something if you want to make pure clean you have the Concord package you can make some Cato application with that the Android package is going Android and going on with view model you have the coin on Droid X stuff don't forget to make tests please everything is on the website insert coin dota yo and please if you like coin please spread the world [Applause] [Music]
Info
Channel: 47 Degrees
Views: 2,720
Rating: undefined out of 5
Keywords: kotlin, Kotlin Day, functional programming, software development, tech talks, android, Kotlin Everywhere
Id: z_wTkxSKzzY
Channel Id: undefined
Length: 47min 59sec (2879 seconds)
Published: Thu Jan 02 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.