Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Koin(Dependency Injection)

Koin(Dependency Injection)

Avatar for Rozina Darediya

Rozina Darediya

November 30, 2019
Tweet

More Decks by Rozina Darediya

Other Decks in Programming

Transcript

  1. Dependency Injection: What is DI : ❖  Design pattern/concept of

    OOPs ❖  Don’t create an object of another class inside a class ❖  Instead, we supply the needed object from outside.
  2. Dependency Injection: What is DI : ❖  Classes often require

    references to other classes ➢  Car() ===> Engine() ➢  These required classes are called dependencies ➢  Car class is dependent on having an instance of the Engine class to run •  Car() creates obj of Engine() •  Tightly coupled/highly dependent •  Engine() need to be change its definition, than Car also need to change its definition.
  3. Definition : In software engineering, dependency injection is a technique

    whereby one object (or static method) supplies the dependencies of another object. A dependency is an object that can be used (a service).
  4. Why DI : ❖  Helps us enable loose coupling ❖ 

    Reduces the boilerplate code ❖  Reusable and clean code ❖  Easy to replace dependencies with fake implementations ❖  Easier to test
  5. Popular libraries for DI : (some names we have heard

    of) ❖  RoboGuice (no longer supported,Inject your View, Resource, System Service, or any other object) ❖  ButterKnife (Field and method binding for Android views) ❖  Dagger (compile-time framework for dependency injection) ❖  Koin (A pragmatic lightweight dependency injection framework)
  6. Dagger and its pitfalls ❖  Initial setup is difficult ❖ 

    Bit complex to learn ❖  Unclear compile time errors ❖  Increased time in compilation process ❖  Uses reflection to some extent
  7. Introduction : KOIN ❖  Pragmatic lightweight DSL dependency injection framework

    ❖  Purely written in Kotlin ❖  Easy, simple, well documented ❖  No proxy ❖  No code generation ❖  No reflection
  8. Install the dependency First get the library into your project.

    You will need to add the following to your module-level build.gradle.
  9. KOIN in three stages According to the official documentation, you

    can start using Koin in three simple stages ❖  Declare a module ❖  Start Koin ❖  Perform an injection
  10. Perform an injection By the way, there are two ways

    of providing the type: via a type parameter or via an explicit type definition: 1.  val toastMessage by inject<ToastMessage>() 2.  val anotherToastMessage : ToastMessage by inject()
  11. Dipper dive with KOIN ❖  With Koin, setting up dependency

    injection is kind of a manual process ❖  We essentially plug our services into the module graphs ❖  These dependencies will later get resolved at runtime
  12. Some key functions Some key functions ❖  module { }

    : ➢  Create a Koin Module or a submodule (inside a module) ➢  It serves as a container ➢  It is a collection of services that should be provided at runtime. ➢  We put all the services that a module should provide in the module block
  13. Some key functions ❖  factory{ } : ➢  Creates instance

    of given class. ➢  new instance every time it’s called. ➢  Can be dropped ➢  Koin will resolve all the dependencies of MyClass
  14. ➢  Manually build the dependency ➢  Used this when want

    to build a dependency based on configurations or other criteria.
  15. Some key functions ❖  single{ } : ➢  Create object

    persist entire lifetime ➢  Can’t be dropped ➢  This can be done in some ways similar to the factory defined above.
  16. Some key functions ❖  get{ } : ➢  Is a

    generic function ➢  Use to resolve any particular dependency that you need ➢  To the requested needed component instance. class Service() class Controller( val view : View)
  17. Read or Write Properties ❖  setProperty/getProperty : ➢  Koin can

    contain configuration properties or values ➢  that can be read and set at runtime ➢  key-value pair container // set the property at run time setProperty("api_url", "http://dummy.dev.com") // get the property val stagingUrl: String = getProperty("api_url")
  18. KOIN component ➢  Koin creates its dependency container when we

    start a Koin ➢  To retrieve dependencies or interact with Koin, you would need to implement KoinComponent ➢  KoinComponent serves as the container context ➢  Allows you to interact with the Koin framework ➢  Access to functions like get, inject, getKoin, viewModel, etc.
  19. ❖  In activity no need of KoinComponent // dependency evaluates

    eagerly val toastMessage : ToastMessage = get() //dependency evaluates lazily val toastMessage : ToastMessage by inject() •  In first, the Object creation gets to the field initialization (will be retrieved from the dependency container) •  In second, it will not be resolved until the class tries to use it
  20. ❖  In ViewModel KoinComponent(ViewModel) is needed ➢  viewModel { }

    definition enables to define a viewModel dependency ➢  Define dependency val activityModule = module { viewModel { ActivityViewModel() } } ➢  Declare viewModel in activity or fragment val activityViewModel: ActivityViewModel by viewModel() ➢  Declare viewModel that is shared between activity and its child fragments val mainActivityViewModel: MainActivityViewModel by sharedViewModel()
  21. ➢  Scope will decide how long is the lifecycle of

    injected object. ➢  It allows you to define local scoped-dependencies ➢  Like - Presenter, View Adapter, or other service components ➢  They are meant to be short-lived within a defined scope, ◦  like an Activity’s scope ➢  Specify the scope_id which is just a unique string to represent the scope definition ➢  scope_id will be used as a reference, ◦  in creating, requesting or closing a scope.
  22. ➢  Define scope: val myPresenterModule = module { scope("myPresenter") {

    MyPresenter() } } ➢  Bind the Scope to the Activity using bind into the onCreate method. override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val scope = getKoin().getOrCreateScope("myPresenter") bindScope(scope) } ➢  scope.close()
  23. ➢  Add library of test : dependencies { // Koin

    testing tools testImplementation 'org.koin:koin-test:$koin_version' } ➢  Just tag your test class with KoinTest ➢  and you will be able to use KoinComponent & testing features ◦  by inject() - lazy inject an instance ◦  get() - retrieve an instance
  24. val testModule = module { single { TestData(4, 2 +

    5) } } data class TestData(val expected: Long, val actual: Long) class ExampleUnitTest : KoinTest { val testData: TestData by inject<TestData>() @Before fun before() { startKoin { modules(testModule) } } @After fun after() { stopKoin() } @Test fun addition_isCorrect() { assertEquals(testData.expected, testData.actual) } }