From d082eebbc88e4d96176c9e35124378f01b210c15 Mon Sep 17 00:00:00 2001
From: Connor Wyatt <connorwyatt1@gmail.com>
Date: Sat, 4 Nov 2023 22:44:50 +0000
Subject: [PATCH] Ensure that DI is exposed

---
 .../common/server/ApplicationConfiguration.kt | 139 ++++++++++--------
 1 file changed, 74 insertions(+), 65 deletions(-)

diff --git a/server/src/main/kotlin/io/connorwyatt/common/server/ApplicationConfiguration.kt b/server/src/main/kotlin/io/connorwyatt/common/server/ApplicationConfiguration.kt
index 8e63279..b3c9fde 100644
--- a/server/src/main/kotlin/io/connorwyatt/common/server/ApplicationConfiguration.kt
+++ b/server/src/main/kotlin/io/connorwyatt/common/server/ApplicationConfiguration.kt
@@ -1,16 +1,11 @@
 package io.connorwyatt.common.server
 
 import io.connorwyatt.common.eventstore.configuration.EventStoreConfiguration
-import io.connorwyatt.common.eventstore.kodein.eventStoreDependenciesModule
 import io.connorwyatt.common.eventstore.ktor.configureEventStore
-import io.connorwyatt.common.http.httpDependenciesModule
 import io.connorwyatt.common.mongodb.configuration.MongoDBConfiguration
-import io.connorwyatt.common.mongodb.kodein.mongoDBDependenciesModule
 import io.connorwyatt.common.mongodb.ktor.configureMongoDB
 import io.connorwyatt.common.rabbitmq.configuration.RabbitMQConfiguration
-import io.connorwyatt.common.rabbitmq.kodein.rabbitMQDependenciesModule
 import io.connorwyatt.common.rabbitmq.ktor.configureRabbitMQ
-import io.connorwyatt.common.time.timeDependenciesModule
 import io.ktor.server.application.*
 import io.ktor.server.plugins.requestvalidation.*
 import io.ktor.server.plugins.statuspages.*
@@ -19,76 +14,90 @@ import kotlinx.coroutines.runBlocking
 import org.kodein.di.DI
 import org.kodein.di.ktor.di
 
-class ApplicationConfiguration {
-    private var diModules = listOf<DI.Module>()
-    private var eventStoreConfiguration: EventStoreConfiguration? = null
-    private var mongoDBConfiguration: MongoDBConfiguration? = null
-    private var rabbitMQConfiguration: RabbitMQConfiguration? = null
-    private var http: Boolean = false
-    private var time: Boolean = false
-    private var configureRequestValidation: (RequestValidationConfig.() -> Unit)? = null
-    private var configureStatusPages: (StatusPagesConfig.() -> Unit)? = null
-    private var configureRouting: (Routing.() -> Unit)? = null
-
-    fun addDIModule(diModule: DI.Module) {
-        diModules = diModules.plus(diModule)
-    }
+class ApplicationConfiguration(block: Builder.() -> Unit) {
+    val di = DI { importAll(builder.diModules) }
 
-    fun addEventStore(eventStoreConfiguration: EventStoreConfiguration) {
-        this.eventStoreConfiguration = eventStoreConfiguration
-    }
+    private val builder: Builder = Builder().apply(block)
 
-    fun addMongoDB(mongoDBConfiguration: MongoDBConfiguration) {
-        this.mongoDBConfiguration = mongoDBConfiguration
+    fun applyTo(application: Application) {
+        application.apply {
+            di { extend(di) }
+            builder.mongoDBConfiguration?.let { runBlocking { configureMongoDB() } }
+            builder.eventStoreConfiguration?.let { configureEventStore(it) }
+            builder.rabbitMQConfiguration?.let { configureRabbitMQ(it) }
+            configureSerialization()
+            builder.configureRequestValidation?.let { configureRequestValidation(it) }
+            configureStatusPages(builder.configureStatusPages)
+            configureCallId()
+            configureCallLogging()
+            builder.configureRouting?.let { configureRouting(it) }
+        }
     }
 
-    fun addRabbitMQ(rabbitMQConfiguration: RabbitMQConfiguration) {
-        this.rabbitMQConfiguration = rabbitMQConfiguration
-    }
+    class Builder internal constructor() {
+        internal var diModules = listOf<DI.Module>()
+            private set
 
-    fun addHttp() {
-        this.http = true
-    }
+        internal var eventStoreConfiguration: EventStoreConfiguration? = null
+            private set
 
-    fun addTime() {
-        this.time = true
-    }
+        internal var mongoDBConfiguration: MongoDBConfiguration? = null
+            private set
 
-    fun configureRequestValidation(configureRequestValidation: RequestValidationConfig.() -> Unit) {
-        this.configureRequestValidation = configureRequestValidation
-    }
+        internal var rabbitMQConfiguration: RabbitMQConfiguration? = null
+            private set
 
-    fun configureStatusPages(configureStatusPages: StatusPagesConfig.() -> Unit) {
-        this.configureStatusPages = configureStatusPages
-    }
+        internal var http: Boolean = false
+            private set
 
-    fun configureRouting(configureRouting: Routing.() -> Unit) {
-        this.configureRouting = configureRouting
-    }
+        internal var time: Boolean = false
+            private set
 
-    fun applyTo(application: Application) {
-        application.apply {
-            di {
-                eventStoreConfiguration?.let { import(eventStoreDependenciesModule(it)) }
-                mongoDBConfiguration?.let { import(mongoDBDependenciesModule(it)) }
-                rabbitMQConfiguration?.let { import(rabbitMQDependenciesModule(it)) }
-                if (http) {
-                    import(httpDependenciesModule)
-                }
-                if (time) {
-                    import(timeDependenciesModule)
-                }
-                importAll(diModules)
-            }
-            mongoDBConfiguration?.let { runBlocking { configureMongoDB() } }
-            eventStoreConfiguration?.let { configureEventStore(it) }
-            rabbitMQConfiguration?.let { configureRabbitMQ(it) }
-            configureSerialization()
-            configureRequestValidation?.let { configureRequestValidation(it) }
-            configureStatusPages(configureStatusPages)
-            configureCallId()
-            configureCallLogging()
-            configureRouting?.let { configureRouting(it) }
+        internal var configureRequestValidation: (RequestValidationConfig.() -> Unit)? = null
+            private set
+
+        internal var configureStatusPages: (StatusPagesConfig.() -> Unit)? = null
+            private set
+
+        internal var configureRouting: (Routing.() -> Unit)? = null
+            private set
+
+        fun addDIModule(diModule: DI.Module) {
+            diModules = diModules.plus(diModule)
+        }
+
+        fun addEventStore(eventStoreConfiguration: EventStoreConfiguration) {
+            this.eventStoreConfiguration = eventStoreConfiguration
+        }
+
+        fun addMongoDB(mongoDBConfiguration: MongoDBConfiguration) {
+            this.mongoDBConfiguration = mongoDBConfiguration
+        }
+
+        fun addRabbitMQ(rabbitMQConfiguration: RabbitMQConfiguration) {
+            this.rabbitMQConfiguration = rabbitMQConfiguration
+        }
+
+        fun addHttp() {
+            this.http = true
+        }
+
+        fun addTime() {
+            this.time = true
+        }
+
+        fun configureRequestValidation(
+            configureRequestValidation: RequestValidationConfig.() -> Unit
+        ) {
+            this.configureRequestValidation = configureRequestValidation
+        }
+
+        fun configureStatusPages(configureStatusPages: StatusPagesConfig.() -> Unit) {
+            this.configureStatusPages = configureStatusPages
+        }
+
+        fun configureRouting(configureRouting: Routing.() -> Unit) {
+            this.configureRouting = configureRouting
         }
     }
 }