I'm looking for recommendations on how to design something without the use of class references.
Kotlin has javaClass() for compatibility with Java code, but otherwise, there are no class references (unless I’m missing something).
What would the best way to design an API such as the following:
fun <T> setLoader(type:Class<T>, loader: Loader<T>) { loaderMap.put(type, loader) }
fun load(file:String, type:Class) { loaderMap.get(type).load(file) }
Reflection and class "literals" are coming, though there is still a lot of work ahead. Meanwhile, you can use recently introduced reified type parameters for inline functions.
inline fun LoaderRegistry.setLoaderFor<reified T>(loader: Loader<T>) = setLoader(javaClass<T>(), loader)
and use it like this
registry.setLoaderFor<MyEntity>(EntityLoader())
depending on how rich is your domain space, there could be more DSLs around it, such as:
// core traits
trait LoaderRegistry {
fun setLoader<T>(klass: Class<T>, loader: Loader<T>)
fun setStrategy<T>(klass: Class<T>, strategy: LoaderStrategy)
}
trait Loader<T> enum class LoaderStrategy {
Singleton
Transient
}
// DSL class LoaderRegistryDescriptor<T>(val registry: LoaderRegistry, val klass: Class<T>)
inline fun LoaderRegistry.describe<reified T>(body: LoaderRegistryDescriptor<T>.() -> Unit)
= LoaderRegistryDescriptor(this, javaClass<T>()).body()
fun <T> LoaderRegistryDescriptor<T>.loader(loader: Loader<T>) = registry.setLoader<T>(klass, loader) fun <T> LoaderRegistryDescriptor<T>.strategy(value: LoaderStrategy) = registry.setStrategy<T>(klass, value)
// domain objects class MyEntity
class EntityLoader : Loader<MyEntity>
fun fn(registry: LoaderRegistry) {
registry.describe<MyEntity> { loader(EntityLoader()) strategy(LoaderStrategy.Singleton) } }
With a little effort you can translate loader and strategy DSL functions to properties, if you wish.
I had a bit of an "Aha" moment. Classes with class objects can be passed around a bit like a class reference. So in my case, where I want to map a type to an instance, I can use the reference to the class object.