Làm quen với Koin và Apply vào MVVM architecture (phần 2)

**Sau khi chúng ta tìm hiểu được các công dụng của koin và cách sử dụng nó thì bây giờ chúng ta sẽ tìm hiểu phần 2 nói về một số cách để sử dụng nó một cách thuần thục hơn **

Với Koin, thiết lập tiêm phụ thuộc là một quy trình thủ công, về cơ bản, bạn cắm các dịch vụ của mình vào các biểu đồ mô-đun và những phụ thuộc này sau đó sẽ được giải quyết khi chạy. Dưới đây là các chức năng chính. module { } - tạo Mô-đun Koin hoặc mô hình con (bên trong mô-đun) factory { } - cung cấp một định nghĩa single { } - cung cấp 1 singleton get() - giải quyết một phụ thuộc thành phần bind - liên kết loại Kotlin bổ sung cho định nghĩa bean đã cho getProperty() - giải quyết 1 property

Module

Định nghĩa mô-đun rất giống với định nghĩa Dagger-2 @Module, nó phục vụ như một thùng chứa cho một bộ sưu tập các dịch vụ nên được cung cấp khi chạy. Bạn đặt tất cả các dịch vụ mà một mô-đun sẽ cung cấp trong khối mô-đun. Ví dụ :

val dataModule = module {

    single<SharedPreferenceManager>()

    single<ContactManager>()

    single { ContactServerManager(get()) }
}

Tạo các module và đưa vào đó các thành phần mà chúng ta cần thiết get và inject ở các nơi tùy ý các bạn

Factory

Một factory cung cấp mục đích đủ điều kiện cho 1 dependency . nó gọi đến kotlin framwork nhưng không giữ lại instance này mà tạo ra cung cấp khi được yêu cầu . Điều này có thể làm 2 cách :

interface SomeInterface {
    fun getSimpleDate(): String
}

class SomeClass(val date: Date): SomeInterface {

    override fun getSimpleDate(): String {
        return SimpleDateFormat.getDateInstance().format(date)
    }
}

val testModule = module {

    // tạo 1 instance để dùng 
    single { Date() }

    // sau đó bạn có thể tự động giải quyết nó 
    factory<SomeClass>()

    // hoặc bạn có thể dùng a factory để biên soạn service đó 
    factory {
        val currentDate = Date()

        [email protected] SomeClass(currentDate)
    }
    // hoặc có thể implementation 1 interface 
    factoryBy<SomeInterface, SomeClass>()
    
    // hoặc giải quyết nó vời 1 block 
    factory<SomeInterface> {
        val currentDate = Date()

        [email protected] SomeClass(currentDate)
    }
}

Tùy vào trường hợp mà bạn có những cách factory một cách hợp lý . nó cung cấp các intance khi cần

Single

Nó đối lập với Factory . nó giữ lại các intance và cũng cấp cho bất cứ nơi nào cần nó . điều này giống với trong Dagger 2 là anotation @Singleton . Ví dụ :

val testModule = module {

    // tạo instance để dùng 
    single { Date() }

    // sau đó tự động giải quyết someclass 
    single<SomeClass>()

    // hoặc bạn có thể dùng một  'single' block để biên soạn  the service
    single {
        val currentDate = Date()

        [email protected] SomeClass(currentDate)
    }
    // hoặc có thể giải quyết 1 implementation cho 1 interface
    singleBy<SomeInterface, SomeClass>()
    
    // hoặc là dùng 1 block 
    single<SomeInterface> {
        val currentDate = Date()

        [email protected] SomeClass(currentDate)
    }
}

Get

Để lấy ra các dependency ở chỗ mà chúng ta cần . Cung cấp các depen cụ thể khi các bạn yêu cầu theo Follow ví dụ bên dưới :

val testModule = module {

    // create one instance to be used
    single { Date() }


    factory<SomeInterface> {
        // resolve dependency within module definition
        val currentDate: Date = get() // or get<Date>()

        [email protected] SomeClass(currentDate)
    }
}

class SomeActivity: AppCompatActivity() {

    private lateinit var someService: SomeInterface

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // .. other setup
      
        // resolve dependency within activity
        someService = get()
    }

    //.... other stuff

}

Bind

Liên kết là một hàm infix giúp giải quyết các loại bổ sung, điều này có nghĩa là gì, bạn tạo một định nghĩa bean và sử dụng liên kết để giải quyết nó như một loại bổ sung, ví dụ :

interface Flammable {
    fun getFlames(): String
}

interface SomeInterface: Flammable {
    fun getSimpleDate(): String
}

class SomeClass(val date: Date): SomeInterface {

    override fun getSimpleDate(): String {
        return SimpleDateFormat.getDateInstance().format(date)
    }

    override fun getFlames(): String {
        return "Look to your sins," +
                " the night is dark and" +
                " full of terrors"
    }
}

val testModule = module {

    // create one instance to be used
    single { Date() }

    // will provide dependency for SomeClass
    // and SomeInterface and Flamable
    single { SomeClass(get()) } bind SomeInterface::class bind Flammable::class
}

class SomeActivity: AppCompatActivity() {

    private lateinit var someService: SomeInterface
    private lateinit var someClass: SomeClass

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // .. other setup

        // will resolve a dependency
        // based on single bean defined above
        someService = get()
        // will resolve the same dependency
        // based on single bean defined above
        someClass = get()

    }

    //.... other stuff

}

Trên đây là 1 số hàm cũng như 1 số property trong koin . chúc các bạn có thể thành thục việc dùng nó .


All Rights Reserved