I am facing following task of providing implementation of the trait as a configuration option. I have following class hierarchy :
trait Storage {
def store()
}
object LocalStorage extends Storage {
def store(){ ... }
}
object RemoteStorage extends Storage {
def store(){ ... }
}
Having a configuration in property file:
storage.class = "com.xxx.LocalStorage"
Having an implementation on the persistence layer:
class CheckPersister{
val storageType = ConfigFactory.load().getString("storage.class")
val storage: Storage = Class.forName(storageType).asInstanceOf[Storage]
...
}
Is there a better way of dealing with this kind of configuration? I am using Typesafe configuration.
Thx
Directly specifying the name of the class in the config file looks like a bad idea. Would something like this be acceptable instead?
storage.location = "local"
class CheckPersister {
val storageType = ConfigFactory.load().getString("storage.class")
val storage: Storage = storageType match {
case "local" => LocalStorage
case "remote" => RemoteStorage
case x => throw new RuntimeException(s"Invalid storage type $x specified")
}
...
}
In this way you can't accidentally instantiate a class you didn't intend.