DEV Community

Cover image for Dagger2 Dependency Injection in Kotlin & Ktor
Aman Bhardwaj
Aman Bhardwaj

Posted on

Dagger2 Dependency Injection in Kotlin & Ktor

Introduction

In this article, we will delve into the world of Dagger2 Dependency Injection (DI) in Kotlin, particularly focusing on integrating it with the Ktor framework. If you've previously worked with Spring Boot, you might be familiar with the concept of dependency injection through annotations like @Autowired. However, Ktor does not provide the same level of abstraction, so we'll explore how to set up dependency injection from scratch using Dagger2 by Google.

Setting Up Dependencies

Before diving into the implementation, let's ensure we have the necessary dependencies in our project. You can find the complete Gradle setup in the provided GitHub repository. Note that I've made some adjustments to the versions, so ensure that your Kotlin, Ktor, and Dagger2 versions are in sync.

// build.gradle

// Kotlin version and plugins
kotlin {
    version = "1.7.20"
    // other Kotlin plugins...
}

// Ktor dependencies
implementation "io.ktor:ktor-server-core:1.7.0"
implementation "io.ktor:ktor-server-netty:1.7.0"

// Dagger2 dependencies
implementation "com.google.dagger:dagger:2.44"
kapt "com.google.dagger:dagger-compiler:2.44"
Enter fullscreen mode Exit fullscreen mode

Project Structure

Let's organize our project structure to accommodate Dagger2. We'll create two packages: modules and components under the dagger package. Additionally, we can introduce layers such as handlers, services, and repos to structure our application.

src
|-- main
    |-- kotlin
        |-- your.package.name
            |-- dagger
                |-- components
                |-- modules
            |-- handlers
            |-- services
            |-- repos
Enter fullscreen mode Exit fullscreen mode

Creating User Handlers

First, let's set up the user handling layers. We'll define an interface UserHandler with a method createUser and provide an implementation for it.

// UserHandler.kt

interface UserHandler {
    fun createUser(user: UserModel): Boolean
}

// UserHandlerImpl.kt

class UserHandlerImpl : UserHandler {
    override fun createUser(user: UserModel): Boolean {
        // Implementation logic (logging for now)
        return true
    }
}
Enter fullscreen mode Exit fullscreen mode

Dagger2 Modules

Now, we'll create Dagger2 modules for our user handling components. Start with the UserHandlerModule.

// UserHandlerModule.kt

@Module
class UserHandlerModule {

    @Provides
    @Singleton
    fun provideUserHandler(): UserHandler {
        return UserHandlerImpl()
    }
}
Enter fullscreen mode Exit fullscreen mode

Dagger2 Components

Next, let's create Dagger2 components for our user handling layers.

// UserHandlerComponent.kt

@Component(modules = [UserHandlerModule::class])
interface UserHandlerComponent {
    fun getUserHandler(): UserHandler
}
Enter fullscreen mode Exit fullscreen mode

Integrating with Ktor
Now, let's integrate our Dagger2 components with Ktor. We'll update our routing configuration to use the UserHandler instance.

// Application.kt

fun Application.module() {
    // Other Ktor configurations...

    install(ContentNegotiation) {
        // Content negotiation configuration...
    }

    val userHandler = DaggerUserHandlerComponent.create().getUserHandler()

    routing {
        route("/users") {
            post {
                val user = call.receive<UserModel>()
                if (userHandler.createUser(user)) {
                    call.respond(HttpStatusCode.Created)
                } else {
                    call.respond(HttpStatusCode.InternalServerError)
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion
In this article, we've successfully integrated Dagger2 for dependency injection in a Kotlin Ktor application. We've organized our project structure, created modules and components, and demonstrated how to inject dependencies into Ktor routes. This lays a solid foundation for future expansion, such as introducing a database layer or integrating with external APIs and for that, checkout my Udemy course:

REST API in Kotlin & Ktor

What you'll learn in this course?

  • Build a REST API in Kotlin & Ktor
  • User PostgreSQL as the Database
  • Structure project with dependency injection using Dagger2
  • Hands on coding tutorials with no slides

I will see you in the next article. Until then, scatter.

You know where to find me:
LinkedIn
YouTube
Github
Udemy

Top comments (0)