Skip to content

Commit 72edd8b

Browse files
committed
feat(#470): add module name verification option to DI
1 parent 89fec07 commit 72edd8b

4 files changed

Lines changed: 44 additions & 4 deletions

File tree

kodein-di/src/commonMain/kotlin/org/kodein/di/DI.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,12 @@ public interface DI : DIAware {
558558
*/
559559
public var fullContainerTreeOnError: Boolean
560560

561+
/**
562+
* If true, importing a module with a duplicate name will throw an exception.
563+
* If false (default), duplicate module names are allowed.
564+
*/
565+
public var verifyModuleNames: Boolean
566+
561567
/**
562568
* The external source is repsonsible for fetching / creating a value when DI cannot find a matching binding.
563569
*/
@@ -703,6 +709,7 @@ public interface DI : DIAware {
703709

704710
public var defaultFullDescriptionOnError: Boolean = false
705711
public var defaultFullContainerTreeOnError: Boolean = false
712+
public var defaultVerifyModuleNames: Boolean = false
706713
}
707714

708715
}

kodein-di/src/commonMain/kotlin/org/kodein/di/internal/DIBuilderImpl.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ internal open class DIBuilderImpl internal constructor(
2222
private val moduleName: String?,
2323
private val prefix: String,
2424
internal val importedModules: MutableSet<String>,
25-
override val containerBuilder: DIContainerBuilderImpl
25+
override val containerBuilder: DIContainerBuilderImpl,
26+
protected open val verifyModuleNames: Boolean
2627
) : DI.Builder {
2728

2829
override val contextType = TypeToken.Any
@@ -276,15 +277,16 @@ internal open class DIBuilderImpl internal constructor(
276277

277278
override fun import(module: DI.Module, allowOverride: Boolean) {
278279
val moduleName = prefix + module.name
279-
if (moduleName.isNotEmpty() && moduleName in importedModules) {
280+
if (verifyModuleNames && moduleName.isNotEmpty() && moduleName in importedModules) {
280281
throw IllegalStateException("Module \"$moduleName\" has already been imported!")
281282
}
282283
importedModules += moduleName
283284
DIBuilderImpl(
284285
moduleName,
285286
prefix + module.prefix,
286287
importedModules,
287-
containerBuilder.subBuilder(allowOverride, module.allowSilentOverride)
288+
containerBuilder.subBuilder(allowOverride, module.allowSilentOverride),
289+
verifyModuleNames
288290
).apply(module.init)
289291
}
290292

@@ -311,13 +313,15 @@ internal open class DIMainBuilderImpl(allowSilentOverride: Boolean) : DIBuilderI
311313
null,
312314
"",
313315
HashSet(),
314-
DIContainerBuilderImpl(true, allowSilentOverride, HashMap(), ArrayList(), ArrayList())
316+
DIContainerBuilderImpl(true, allowSilentOverride, HashMap(), ArrayList(), ArrayList()),
317+
DI.defaultVerifyModuleNames
315318
), DI.MainBuilder {
316319

317320
override val externalSources: MutableList<ExternalSource> = ArrayList()
318321

319322
override var fullDescriptionOnError: Boolean = DI.defaultFullDescriptionOnError
320323
override var fullContainerTreeOnError: Boolean = DI.defaultFullContainerTreeOnError
324+
override var verifyModuleNames: Boolean = DI.defaultVerifyModuleNames
321325

322326
override fun extend(di: DI, allowOverride: Boolean, copy: Copy) {
323327
val keys = copy.keySet(di.container.tree)

kodein-di/src/commonTest/kotlin/org/kodein/di/Tests_10_Module.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Tests_10_Module {
4848

4949
val ex = assertFailsWith<IllegalStateException> {
5050
DI {
51+
verifyModuleNames = true
5152
import(module)
5253
import(module)
5354
}
@@ -202,4 +203,31 @@ class Tests_10_Module {
202203

203204
assertFailsWith<IllegalStateException> { DI.Module {}.name }
204205
}
206+
207+
@Test
208+
fun test_07_ModuleImportTwiceWithVerificationDisabled() {
209+
val module = DI.Module("test") {}
210+
211+
// Should not throw an exception when verifyModuleNames is false
212+
DI {
213+
verifyModuleNames = false
214+
import(module)
215+
import(module)
216+
}
217+
}
218+
219+
@Test
220+
fun test_08_ModuleImportTwiceWithVerificationEnabled() {
221+
val module = DI.Module("test") {}
222+
223+
val ex = assertFailsWith<IllegalStateException> {
224+
DI {
225+
verifyModuleNames = true
226+
import(module)
227+
import(module)
228+
}
229+
}
230+
231+
assertEquals("Module \"test\" has already been imported!", ex.message)
232+
}
205233
}

kodein-di/src/jvmTest/kotlin/org/kodein/di/GenericJvmTests_10_Module.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class GenericJvmTests_10_Module {
5151

5252
val ex = assertFailsWith<IllegalStateException> {
5353
DI {
54+
verifyModuleNames = true
5455
import(module)
5556
import(module)
5657
}

0 commit comments

Comments
 (0)