From 1462db5d5f6d76ac6d2e66bf1c0450f9ff869268 Mon Sep 17 00:00:00 2001 From: Oguzhan Soykan Date: Wed, 30 Oct 2024 09:49:34 +0100 Subject: [PATCH] Move mapping mediator builder into core package --- .../trendyol/kediatr/DependencyProvider.kt | 9 +++ .../kediatr/MappingDependencyProvider.kt | 56 +++++++++++++++++++ .../com/trendyol/kediatr/MediatorTests.kt | 3 +- .../testing/MappingDependencyProvider.kt | 46 --------------- .../trendyol/kediatr/testing/convention.kt | 9 +-- 5 files changed, 68 insertions(+), 55 deletions(-) create mode 100644 projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MappingDependencyProvider.kt delete mode 100644 projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/MappingDependencyProvider.kt diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt index 9514ef1..0cca474 100644 --- a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt +++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/DependencyProvider.kt @@ -1,7 +1,16 @@ package com.trendyol.kediatr +/** + * Dependency provider interface. + */ interface DependencyProvider { + /** + * Gets a single instance of the specified class. + */ fun getSingleInstanceOf(clazz: Class): T + /** + * Gets all subtypes of the specified class. + */ fun getSubTypesOf(clazz: Class): Collection> } diff --git a/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MappingDependencyProvider.kt b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MappingDependencyProvider.kt new file mode 100644 index 0000000..2c3c28b --- /dev/null +++ b/projects/kediatr-core/src/main/kotlin/com/trendyol/kediatr/MappingDependencyProvider.kt @@ -0,0 +1,56 @@ +@file:Suppress("UNCHECKED_CAST") + +package com.trendyol.kediatr + +import java.lang.reflect.ParameterizedType + +/** + * Dependency provider that uses a map to resolve dependencies. + * @param handlerMap A map that contains the handlers. + * The key is the handler class and the value is the handler instance. + * @see DependencyProvider + */ +class MappingDependencyProvider( + private val handlerMap: HashMap, Any> +) : DependencyProvider { + override fun getSingleInstanceOf(clazz: Class): T = handlerMap[clazz] as T + + override fun getSubTypesOf(clazz: Class): Collection> = handlerMap.keys + .filter { isCompatibleType(it, clazz) } + .map { it as Class } + + private fun isCompatibleType( + handler: Class<*>, + interfaceOrBaseClass: Class + ): Boolean = when { + interfaceOrBaseClass.isAssignableFrom(handler) -> true + handler.genericInterfaces + .filterIsInstance() + .any { it.rawType == interfaceOrBaseClass } -> true + + else -> when (val superclass = handler.genericSuperclass) { + is ParameterizedType -> { + val inheritedHandler = superclass.rawType as Class<*> + inheritedHandler.genericInterfaces + .filterIsInstance() + .any { it.rawType == interfaceOrBaseClass } + } + + is Class<*> -> interfaceOrBaseClass.isAssignableFrom(superclass) + else -> false + } + } + + companion object { + /** + * Creates a mediator with the given handlers. + * @param handlers The handlers to be used by the mediator. Can also be [PipelineBehavior] instances. + * @return A mediator instance. + */ + fun createMediator(handlers: List = emptyList()): Mediator { + val provider = MappingDependencyProvider(handlers.associateBy { it.javaClass } as HashMap, Any>) + val mediator = MediatorBuilder(provider).build() + return mediator + } + } +} diff --git a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/MediatorTests.kt b/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/MediatorTests.kt index 5f68ed2..f8e31c1 100644 --- a/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/MediatorTests.kt +++ b/projects/kediatr-core/src/test/kotlin/com/trendyol/kediatr/MediatorTests.kt @@ -1,12 +1,13 @@ package com.trendyol.kediatr +import com.trendyol.kediatr.MappingDependencyProvider.Companion.createMediator import com.trendyol.kediatr.testing.* import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test class MediatorTests : MediatorUseCases() { override fun provideMediator(): Mediator = createMediator( - types = listOf( + handlers = listOf( TestCommandHandler(mediator = { testMediator }), TestPipelineCommandHandler(mediator = { testMediator }), TestCommandWithResultCommandHandler(mediator = { testMediator }), diff --git a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/MappingDependencyProvider.kt b/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/MappingDependencyProvider.kt deleted file mode 100644 index fcd1fc4..0000000 --- a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/MappingDependencyProvider.kt +++ /dev/null @@ -1,46 +0,0 @@ -@file:Suppress("UNCHECKED_CAST") - -package com.trendyol.kediatr.testing - -import com.trendyol.kediatr.DependencyProvider -import java.lang.reflect.ParameterizedType - -class MappingDependencyProvider( - private val handlerMap: HashMap, Any> -) : DependencyProvider { - override fun getSingleInstanceOf(clazz: Class): T = handlerMap[clazz] as T - - override fun getSubTypesOf(clazz: Class): Collection> = handlerMap - .filter { filterInternal(it.key, clazz) } - .map { it.key as Class } - - private fun filterInternal( - handler: Class<*>, - interfaceOrBaseClass: Class - ): Boolean { - if (interfaceOrBaseClass.isAssignableFrom(handler)) return true - - if (handler.genericInterfaces - .filterIsInstance() - .any { it.rawType == interfaceOrBaseClass } - ) { - return true - } - - return when (handler.genericSuperclass) { - is ParameterizedType -> { - val inheritedHandler = (handler.genericSuperclass as ParameterizedType).rawType as Class<*> - inheritedHandler.genericInterfaces - .filterIsInstance() - .any { it.rawType == interfaceOrBaseClass } - } - - is Class<*> -> { - val inheritedHandler = (handler.genericSuperclass as Class<*>) - interfaceOrBaseClass.isAssignableFrom(inheritedHandler) - } - - else -> false - } - } -} diff --git a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/convention.kt b/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/convention.kt index 213adcb..fd66540 100644 --- a/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/convention.kt +++ b/projects/kediatr-core/src/testFixtures/kotlin/com/trendyol/kediatr/testing/convention.kt @@ -1,16 +1,9 @@ package com.trendyol.kediatr.testing -import com.trendyol.kediatr.* +import com.trendyol.kediatr.Mediator -@Suppress("UNCHECKED_CAST") abstract class MediatorTestConvention { abstract fun provideMediator(): Mediator val testMediator by lazy { provideMediator() } - - protected fun createMediator(types: List = emptyList()): Mediator { - val provider = MappingDependencyProvider(types.associateBy { it.javaClass } as HashMap, Any>) - val mediator = MediatorBuilder(provider).build() - return mediator - } }