Am I correct in my understanding that `object` s h...
# getting-started
h
Am I correct in my understanding that
object
s have all the strengths and weaknesses of a regular Java static singleton?
I am juggling an
object
that is actually a data source and I can't make it work nicely with testing where I have to inject some other than standard values.
Should I just bite down and convert it to a class and pass the instance to wherever it is needed? Like I would in Java.
j
One of the major problems of singletons is that they are accessible from anywhere and people don't inject them, so classes are coupled to the singleton implementation. If you use an interface, and you inject it, you can still declare an object as a default implementation.
💯 1
h
Really hurting me now that the object is reading system variables to initialize itself but now I am starting some dockers using testcontainers and they get different ports and hosts and such but I can't set any of those system variables.
I think I have to change it. It's just so viral and I will have to change in over 200 places....
Intellij will help for sure but still....
y
If the project is internal or bleeding-edge enough, you might also want to consider using
context
receivers as a mechanism to pass that object around. You'd simply make an
interface
out of the object, use that as a
context(MyInterface)
, and then at the very edge of your program you'd initialize the
MyInterface
object and use it in a
with
to pass it to those objects
h
Any example code I can look at @Youssef Shoaib [MOD]?
It seems interesting so I wouldneed to read up a little
Extension functions? Is it the same?
y
Very similar to extensions yes. I'll try to find some more meaningful example code, but it'd go something like this:
Copy code
data class Config(val hostName: String, val port: Int)
class ConfigContext(val config: Config)
// Depending on taste, you might want to use just Config as a context, instead of a separate ConfigContext.
// It just depends on whether you want to access hostName directly, or you prefer to call config.hostName

context(ConfigContext)
fun connect() {
  makeConnectionWith("${config.hostName}:${config.port}")
}
context(Config)
fun shutdown() {
  shutdownServer("$hostName:$port")
}

// Usage

fun main() {
  with(ConfigContext(Config(/* query system properties */))) {
    connect()
    if(shouldShutdown) shutdown()
  }
}
j
@Henrik Johansson

I found this video really interestingâ–¾

to introduce someone (including me) to context receivers.