22/11/2018, 23:47

Viết lại một thư viện dependency injection của Java bằng Kotlin

Kotlin là một ngôn ngữ được phát triển từ Java, chúng ta có thể viết một chương trình bằng Kotlin với code ngắn gọn hơn so với viết bằng Java. Và khả năng tương tác của Kotlin với Java giúp chúng ta dễ dàng kết hợp nó vào các ứng dụng hiện tại hoặc viết ứng dụng mới, trong khi vẫn có quyền tự do sử ...

Kotlin là một ngôn ngữ được phát triển từ Java, chúng ta có thể viết một chương trình bằng Kotlin với code ngắn gọn hơn so với viết bằng Java. Và khả năng tương tác của Kotlin với Java giúp chúng ta dễ dàng kết hợp nó vào các ứng dụng hiện tại hoặc viết ứng dụng mới, trong khi vẫn có quyền tự do sử dụng các thư viện Java hiện hành.

Tuy nhiên, khi các thư viện này được viết bằng Java, việc sử dụng chúng trong Kotlin thường dẫn việc sử dụng cú pháp giống như Java. Điều này không có nghĩa là chúng ta cần phải "reinvent the wheel" và viết một phiên bản Kotlin của thư viện đó, nhưng chúng ta có thể viết một số lớp phụ trợ bằng Kotlin.

Khi nói đến dependency injection, tôi không phải là một fan lớn của Dagger vì cần rất nhiều đoạn code vô lý cần dùng để thiết lập nó. Ngoài ra nó không thực sự tốt để thử nghiệm, và với tôi thử nghiệm là một trong những lý do cho việc dùng dependency injection ở nơi đầu tiên. Vì vậy, tôi thích cách tiếp cận của Toothpick. Nhưng việc sử dụng nó trong dự án Kotlin đã dẫn tôi tới việc tôi cần cải thiện nó khi mắt tôi đau ^^.

Hãy xem cách chúng tôi kết nối một số class với một module:

val module = Module()
module.bind(Repository::class.java).to(DbRepository::class.java)    
module.bind(Scheduler::class.java).toInstance(DefaultScheduler())
module.bind(Api::class.java).toProviderInstance(ApiProvider())

Toothpick có thể liên kết một class với một class khác hoặc một instance hiện có hoặc một provider class có thể tạo class cần thiết khi chạy.

Trước tiên, hãy làm điều này tốt hơn một chút với Kotlin:

val module = Module().apply {
    bind(Repository::class.java).to(DataBaseRepository::class.java)
    bind(Scheduler::class.java).toInstance(DefaultScheduler())
    bind(Api::class.java).toProviderInstance(ApiProvider())
}

Một số điều khiến chúng ta bận tâm:

to là một hàm mở rộng hiện có để tạo instance của Pair. Có cùng tên, thật dễ dàng để làm hỏng điều này ở đây mà không hề nhận thấy. Ràng buộc của bạn có thể không ràng buộc một thứ nào đó nhưng sẽ tạo ra một instance của Pair không được sử dụng.

Vì vậy, chúng ta cần phải viết nó như thế này để đảm bảo rằng có thể nhận được giá trị bên phải của hàm to :

bind(Repository::class.java).`to`(DataBaseRepository::class.java)

Và như vậy, đoạn code của chúng ta đã trở nên xấu xí             </div>
            
            <div class=

0