خانه » Dependency injection » Koin قسمت دوم

Koin قسمت دوم

در قسمت قبلی آموزش : Koin را وارد کنید (قسمت اول) به صورت خیلی ساده در مورد Dependency injection یا همون تزریق وابستگی توضیح دادم و پروژه ساده ای رو باهم شروع کردیم که Source پروژه رو هم در github قرار دادم: https://github.com/eiliyaabedini/koin-sample

در ادامه این آموزش ها بیشتر به Koin می پردازیم.

تا اینجای پروژه ما یک کلاس DataProvider داریم که کارش تامین دیتای مورد نیاز برای نمایش در MainActivity بود و کلاس AppModule که داخلش نحوه تامین DataProvider توسط Koin رو مشخص کردیم.

حالا قصد دارم دیتای مورد نیاز برای نمایش روی صفحه رو از shared preferences بخونم ، یعنی کلاس DataProvider ما حالا به جای اینکه دیتارو به صورت HardCode شده برگردونه ، دیتارو از shared preferences می خونه و برمی گردونه.

برای انجام این کار و کار با shared preferences من ترجیح میدم از لایبرری که قبلا واسه کار با shared preferences نوشته بودم استفاده کنم، یعنی لایبرری SharedDataAccess برای استفاده از این لایبرری در کاتلین ابتدا باید یک interface درست کرد با فیلد های دلخواه سپس باید با استفاده از کد زیر یک instance از کلاس مورد نظر ساخت:

اینترفیس :

interface SharedModel : SharedDefaultValues {
    var userId: String
    var token: String
    var userName: String
}

ساخت instance با کمک لایبرری

val sharedModel = SharedDataAccess(this).create(SharedModel::class.java)

قصد ندارم در این آموزش در مورد لایبرری توضیح بدم و در صورت تمایل میتونید از این لینک در مورد لایبرری بیشتر بخونید: لایبرری SharedDataAccess

فقط توضیح کوتاهی که در مورد نحوه عملکرد این لایبرری میدم اینه که بعد از ساخت اینترفیس و ساخت یک instance از اون به کمک SharedDataAccess بدنه متد های get و set را می نویسد ، مثلا زمانی که قصد مقدار دهی به userId رو داریم، کافی است به این شکل مقدار دهی کنیم:

sharedModel.userId = “Test”

و زمانی که قصد خواندن اطلاعات رو داریم می توانیم به شکل زیر دیتا را بخوانیم:

var userId = sharedModel.userId

خوب تا اینجا برای این لایبرری کافی هست، حالا قصد دارم از این لایبرری استفاده کنم و دیتارو از sharedModel بخونیم.

برای اینکار من لایبرری SharedDataAccess رو به پروژه اضافه می کنم:

allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}

س

dependencies {
    implementation 'com.github.eiliyaabedini:lib-sharedDataAccess:1.0.2'
}

سپس اینترفیس SharedModel رو به شکل زیر می سازم:

package ir.iact.koinSample

import ir.iact.sharedData.SharedDefaultValues

interface SharedModel : SharedDefaultValues {
    var username: String
}

حالا قصد دارم که یک instance از اون رو بسازم ، اما قصد دارم که یک بار اون رو بسازم و در کل برنامه از اون استفاده کنم، قبلا این کار رو به شکل یک آبجکت static می کردم و معمولان توی کلاس Application می ساختم، اما الان میتونم از Koin استفاده کنم و به شکل زیر یک instance از اون رو بسازم:

single {
        SharedDataAccess(get()).create(SharedModel::class.java) as SharedModel 
    }

خوب من این نسخه رو به شکل singleton ساختم تا همه جا از همین نسخه به من بده و هر دفعه این خط کد اجرا نشه، در بخش اول این کد عبارتی رو می بینیم به شکل get() که کمی عجیب هست، در واقع وقتی از SharedDataAccess استفاده می کنیم نیاز به Context داریم، خوب ما هم برای اینکه به اون Context رو بدیم از get() استفاده می کنیم، با این کار get() که یکی از متد های Koin هست، وابستگی مورد نیاز ما رو تامین می کنه ، مثل inject اما inject به صورت lazy کار می کنه و get() به صورت آنی.

خوب از کجا می فهمه چی رو باید تامین کنه: از نوع ورودی متد

از کجا Context رو تهییه می کنه؟! : زمانی که برای اولین بار Koin رو start کردیم به عنوان اولین پارامتر context رو بهش دادیم یعنی این خط:

        startKoin(applicationContext, listOf(appModule))

خوب حالا که این کار رو کردیم Koin متوجه شد که چطور باید SharedModel رو برای ما تهییه کند. از اینجا به بعد من قصد استفاده از SharedModel رو در  DataProvider دارم، خوب برای انجام این کار در Koin به ۲ صورت میتونیم کار کنیم، یکی اینکه مثل نحوه ای که در MainActivity استفاده کردیم، از inject() استفاده کنیم و یا اینکه در Constructor کلاس DataProvider وابستگی های لازم رو به عنوان ورودی بگیریم (dependencies) و زمان ساختن instance در AppModule با get() اون رو مقدار دهی کنیم ، برای فهم بیشتر مثال زیر رو نگاه کنید:

کلاس DataProvider:

package ir.iact.koinSample

class DataProvider(
    private val sharedModel: SharedModel
) {
    fun getUserName(): String {
        return sharedModel.username
    }
}

کلاس AppModule:

package ir.iact.koinSample

import ir.iact.sharedData.SharedDataAccess
import org.koin.dsl.module.module

val appModule = module {
    single {
        DataProvider(
            sharedModel = get()
        )
    }

    single {
        SharedDataAccess(get()).create(SharedModel::class.java) as SharedModel
    }
}

همانطور که می بینید در اینجا هم مثل SharedDataAccess که برای تامین Context از get() استفاده کردیم، برای تامین sharedModel هم از get() استفاده کردیم، به این شکل Koin متوجه می شود برای ساخت DataProvider نیاز به sharedModel داره و برای ساخت SharedDataAccess به Context و همینطور dependency های لازم رو ساخته و در جاهای مورد نیاز (جاهایی که get() یا inject() فراخوانی شده) استفاده می کند.

(Commit: Step 5: Add SharedDataAccess)

خوب اینجا هم نحوه استفاده از Koin برای مقدار دهی به ورودی Constructor ها هم آشنا شدید.

خوب حالا چند امکان دیگر رو بررسی می کنیم:

  • زمانی که قصد داریم هر دفعه یک instance جدید برای شما ساخته شود و به عبارتی singleton نباشد به جای استفاده از عبارت single از factory استفاده می کنیم.
val androidModule = module {
    // a factory of Presenter
    factory { Presenter() }
}
  • زمانی که در یک کلاس قصد استفاده از inject() رو داریم و اگر این کلاس Activityیا Fragment نیست، (مثلا Broadcast receiver) باید KoinComponent رو implement کنید
class MyComponent : KoinComponent {

    // lazy inject Koin instance
    val myService : MyService by inject()

    // or
    // eager inject Koin instance
    val myService : MyService get()
}

 

خوب امیدوارم این آموزش براتون مفید بوده باشه، کد های مربوط به این آموزش رو میتونید در github ببینید.

https://github.com/eiliyaabedini/koin-sample

برچسب ها:
پست قبلی
پست بعدی

درباره ایلیا عابدینی

برنامه نویس اندروید و کارشناس مهندسی پزشکی، نفر سوم مسابقه برنامه نویسی اندروید http://www.schallenge.ir ، از سال 92 برنامه نویسی اندروید رو شروع کردم و در حال حاضر در شرکت ارتباط کنترل فراگستر در حال توسعه اپلیکیشن های اندرویدی می باشدم ، این وبلاگ رو ساختم تا تجربیات روزانه و مفید خودم رو داخل اون بزارم. رزومه : iact.ir/cv

دیدگاهتان را ثبت کنید

آدرس ایمیل شما منتشر نمی شود.علامت دارها لازمند. *

*

رفتن به بالا