PHpullh
학습 라이브러리/Kotlin/DI - 의존성 주입 (Koin)

KOTLIN · 디자인패턴

DI - 의존성 주입 (Koin)

Koin을 사용한 경량 의존성 주입 패턴입니다. DSL로 모듈을 정의하고 런타임에 의존성을 주입합니다.

디자인패턴중급dikoindependency-injectionioc

핵심 설명

Koin을 사용한 경량 의존성 주입 패턴입니다. DSL로 모듈을 정의하고 런타임에 의존성을 주입합니다.

Kotlin code

// Koin 개념 시뮬레이션 (실제: org.koin:koin-core)
class Container {
    val factories = mutableMapOf<String, () -> Any>()
    val singletons = mutableMapOf<String, Any>()

    inline fun <reified T : Any> single(noinline factory: () -> T) {
        factories[T::class.simpleName!!] = factory
    }
    inline fun <reified T : Any> get(): T {
        val key = T::class.simpleName!!
        return singletons.getOrPut(key) { factories[key]!!() } as T
    }
}

interface Logger { fun log(msg: String) }
interface UserRepo { fun find(id: String): String }

class ConsoleLogger : Logger {
    override fun log(msg: String) = println("[LOG] $msg")
}
class UserRepoImpl(private val logger: Logger) : UserRepo {
    override fun find(id: String): String {
        logger.log("사용자 조회: $id")
        return "User-$id"
    }
}

class UserService(private val repo: UserRepo, private val logger: Logger) {
    fun getUser(id: String): String {
        logger.log("서비스 호출")
        return repo.find(id)
    }
}

fun main() {
    val di = Container()
    di.single<Logger> { ConsoleLogger() }
    di.single<UserRepo> { UserRepoImpl(di.get()) }
    di.single { UserService(di.get(), di.get()) }

    val service = di.get<UserService>()
    println(service.getUser("001"))
}

학습 팁

Koin의 single은 싱글톤, factory는 매번 새 인스턴스를 생성합니다. 상태 없는 서비스에는 single을 사용하세요.

주의할 점

순환 의존성(A→B→A)이 있으면 스택 오버플로가 발생합니다. 인터페이스로 의존성을 역전시켜 순환을 끊으세요.

자주 묻는 질문

DI - 의존성 주입 (Koin)란 무엇인가요?

Koin을 사용한 경량 의존성 주입 패턴입니다. DSL로 모듈을 정의하고 런타임에 의존성을 주입합니다.

DI - 의존성 주입 (Koin) 학습 시 주의할 점은 무엇인가요?

순환 의존성(A→B→A)이 있으면 스택 오버플로가 발생합니다. 인터페이스로 의존성을 역전시켜 순환을 끊으세요.