본문 바로가기
Develop/Android

android Koin 을 이용한 의존성 주입 알아보기

by 라이프레이서 2020. 7. 29.

목차

    반응형

    이번에는 Koin 를 활용한 android 의존성 주입에 대해 알아보도록 하겠습니다.(Dependency Injection)

    의존성 주입이란 무엇일까요?

    의존성 주입이란 외부에서 의존 객체를 생성하여 넘겨주는 것을 의미합니다.

    A 클래스가 B Class를 의존할 때 (B 클래스를 이용하여 해당 클래스 내부의 동작을 이용하는 등) A 클래스 내부에서 B클래스에 해당하는 Object를 생성하지 않고, 외부에서 생성하여 넘겨주면 의존성을 주입했다고 표현합니다.

    A 객체에서 B 클래스에 해당하는 객체 직접 생성하여 의존
    외부에서 B클래스 객체 생성하여 전달. 의존성 주입

    외부에서 생성된 객체를 넘겨 받는다고 하는데, 여기서 외부는 어떤 곳을 말하는 걸까요?

    의존성 주입을 위해서는 객체를 생성하고 넘겨줄 외부의 무언가가 필요합니다.

    의존성 주입은 왜 필요할까요?

    의존성 주입을 사용하면, 의존성 파라미터를 생성자에 작성하지 않아도 되므로 보일러 플레이트 코드를 많이 줄일 수 있습니다.

    * 보일러 플레이트 코드란? 최소한의 변경으로 여러 곳에서 재사용되며, 반복적으로 비슷한 형태를 띄는 코드를 말합니다. 때문에 이를 줄임으로써 보다 유연한 프로그래밍이 가능해집니다. 또한 코드끼리의 결합도를 낮춰 확장성을 높여줍니다.

    의존성 주입을 위해서는 Dagger2를 이용한 방법도 있지만, 진입 장벽이 높기 때문에 처음 의존성 주입을 접하는 입장으로서 Koin을 이용해 감을 잡아보고자 합니다.

    아래는 공식문서 사이트 입니다. 최신 버전의 gradle version을 확인하세요!

     

    InsertKoinIO/koin

    Koin - a pragmatic lightweight dependency injection framework for Kotlin - InsertKoinIO/koin

    github.com

    Koin DSL - (Koin을 사용할 때에만 특화된 언어를 Koin DSL 이라 합니다)

    module - Koin 모듈을 생성합니다

    factory - 매번 inject 할때마다 인스턴스 생성합니다.

    single - App전체 주기동안 계속 살아서 이용할 수 있는 싱글톤 객체를 생성합니다.

    get - 컴포넌트내에서 get()자리에 들어갈 파라미터 객체를 알아서 주입해줍니다.

    bind - 종속시킬 class나 interface를 주입합니다.

    gradle 설정

    buildscript {
        ext.kotlin_version = '1.3.72'
        ext.koin_version = '2.1.6' // <- 여기서 Koin 버전 설정
        repositories {
            google()
            jcenter() // <- 여기 jcenter()를 확인합니다.
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.6.0'
            classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
            classpath 'com.google.gms:google-services:4.3.3'
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    
    allprojects {
        repositories {
            google()
            jcenter() 
        }
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }

    module수준 gradle 설정

    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
        implementation 'androidx.appcompat:appcompat:1.1.0'
        implementation 'androidx.core:core-ktx:1.3.0'
        implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'androidx.test.ext:junit:1.1.1'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    
        // Koin for Kotlin
        implementation "org.koin:koin-core:$koin_version"
        // Koin extended & experimental features
        implementation "org.koin:koin-core-ext:$koin_version"
        // Koin for Unit tests
        testImplementation "org.koin:koin-test:$koin_version"
    
        // Koin for Android
        implementation "org.koin:koin-android:$koin_version"
        // Koin Android Scope features
        implementation "org.koin:koin-android-scope:$koin_version"
        // Koin Android ViewModel features
        implementation "org.koin:koin-android-viewmodel:$koin_version"
        // Koin Android Experimental features
        implementation "org.koin:koin-android-ext:$koin_version"
    
        // Koin AndroidX Scope features
        implementation "org.koin:koin-androidx-scope:$koin_version"
        // Koin AndroidX ViewModel features
        implementation "org.koin:koin-androidx-viewmodel:$koin_version"
        // Koin AndroidX Experimental features
        implementation "org.koin:koin-androidx-ext:$koin_version"
    }
    

    Koin 이용하여 의존성 주입 구현하기

    Koin을 이용한 의존성 주입은 아래와 같은 순서로 진행됩니다.
    1. 모듈 생성하기 (Koin DSL)
    2. Android Application Class에서 startKoin()으로 실행하기
    3. 의존성 주입

    그럼 순서대로 한 번 진행해보겠습니다.

    1. 모듈 생성하기

    class MyModule(private val context : Context) {
        fun showToast() {
            Toast.makeText(context,"실행되었습니다",Toast.LENGTH_SHORT).show()
        }
    }
    val appModule = module {
        single { MyModule( get() ) }
    }

    위와 같이 MyModule 이라는 이름으로 context를 필요로 하는 클래스 하나를 만들어줍니다.
    이 class의 showToast()를 호출하도록 하는 것이 이번 포스팅에서의 목표입니다.

    이후 appModule이라는 이름으로 module을 하나 생성해줍니다.
    이 module에서는 singleton 형태로 MyModule 객체를 만들어줄것입니다.

    • singleton은 위에서 말씀드렸다 시피 App전체 주기동안 계속 살아서 이용할 수 있는 객체를 뜻합니다. *

    이때 MyModule은 context를 전달받아야 하는데, get()을 적어주면 라이브러리가 알아서 의존성을 부여해줍니다.

    2. Android Application Class에서 startKoin()으로 실행하기

    class MyApplication : Application() {
        override fun onCreate() {
            super.onCreate()
            startKoin {
                androidContext(this@MyApplication)
                modules(appModule)
            }
        }
    }

    이제 Application()을 상속받는 클래스를 만들어주고, onCreate를 재정의합니다.
    여기 startKoin을 작성하여 모듈을 추가하도록 합니다.
    modules 안에는 여러 module이 들어갈 수 있습니다.

    이렇게 만들어진 MyApplication을 AndroidManifest.xml에 등록해주어야 합니다.

     //AndroidManifest.xml의 application 태그 안에 name 속성에다가 만들어준 class 이름을 적어줍니다.
     <application
            android:name=".MyApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">

    3. 의존성 주입

    그럼 준비는 끝났습니다.
    MainActivity에서 의존성을 주입하여 사용해보도록 하겠습니다.

    class MainActivity : AppCompatActivity() {
        private val myModule : MyModule by inject()
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            myModule.showToast()
        }
    }

    사용할때는 변수 선언과 타입을 지정해주고 by inject()를 해주면 의존성이 주입됩니다.
    이 변수를 통해 MyModule 클래스의 showToast()예 접근할 수 있습니다.

    처음 실행시 실행되었습니다 Toast가 성공적으로 호출되는 것을 볼 수 있습니다!

     

    이렇게 오늘은 Android Koin 라이브러리를 활용한 의존성 주입에 대해 알아보았습니다.

    반응형