Cake Pattern: how to share an instance?
I have a config component in my Scala project.
Obviously, I don't want to have more than one instance of this component. I'm using the cake template, but I'm not sure how to set it up to suit my requirements:
// Library
// =================================================
trait ConfigComp {
trait Config {
def get(k: String): String
}
def config: Config
}
trait QueueComp {
self: ConfigComp =>
class Queue {
val key = config.get("some-key")
}
lazy val queue = new Queue
}
// Application
// =================================================
trait MyConfig extends ConfigComp {
lazy val config = new Config {
println("INITIALIZING CONFIG")
def get(k: String) = "value"
}
}
object Frontend extends QueueComp with MyConfig
object Backend extends QueueComp with MyConfig
Frontend.queue.key
Backend.queue.key
prints:
INITIALIZING CONFIG
INITIALIZING CONFIG
How do I force the cake template to exchange an anonymous instance Config
?
source to share
Something like that?
// Library
// =================================================
trait Config {
def get(k: String): String
}
trait ConfigComp {
def config: Config
}
trait QueueComp {
self: ConfigComp =>
class Queue {
val key = config.get("some-key")
}
lazy val queue = new Queue
}
// Application
// =================================================
object SingleConfig extends ConfigComp {
lazy val config = new Config {
println("INITIALIZING CONFIG")
def get(k: String) = "value"
}
}
object Frontend extends QueueComp with ConfigComp {
val config = SingleConfig.config
}
object Backend extends QueueComp with ConfigComp {
val config = SingleConfig.config
}
Frontend.queue.key
Backend.queue.key
If your trait Config
is inside ConfigComp
, I could not fool these errors like:
error: type mismatch;
found : MyConfig.Config
required: Frontend.Config
(which expands to) Frontend.Config
override def config = MyConfig.config
error: type mismatch;
found : MyConfig.Config
required: Backend.Config
(which expands to) Backend.Config
override def config = MyConfig.config
source to share
As mentioned by om-nom-nom, you want to use a singleton, and therefore MyConfig
must use config
, which is initialized in an object. In the second question , the following error occurred in the gist :
[error] overriding method config in trait ConfigComp of type => MyConfig.this.Config;
[error] lazy value config has incompatible type
[error] lazy val config = MyConfig.config
[error] ^
[error] one error found
essentially tells you exactly the problem. MyConfig.this.Config
not equal to object MyConfig.this.Config
. To make it clearer, change your code to the following:
object MyConfigSingleton extends ConfigComp {
val config = new Config {
println("INITIALIZING CONFIG")
def get(k: String) = "value"
}
}
trait MyConfig extends ConfigComp {
lazy val config = MyConfigSingleton.config
}
Here type MyConfig.this.Config != MyConfigSingleton.this.Config
source to share