How about injecting this
by setter, not by constructor
?
For example:
interface SmsAuthentication {
fun withFlow(flow: Flow)
fun auth()
}
class DefaultSmsAuthentication() : SmsAuthentication {
var flow: Flow? = null
override fun withFlow(flow: Flow) {
this.flow = flow
}
override fun auth() {
flow?.proceed()
}
}
class SomeFlow : Flow, SmsAuthentication by DefaultSmsAuthentication() {
init {
withFlow(this)
}
}
However, you need to call withFlow()
in constructor
by hand every time. You may forget to call it.
You may want to have SmsAuthentication
as a property. So you just inject it by lazy
and call it in need. I think it's safer way.
class SomeFlow : Flow, SmsAuthentication {
val auth by lazy { DefaultSmsAuthentication(this) }
override fun auth() {
auth.auth()
}
}
You can also apply Decorator pattern, conversely:
class DefaultSmsAuthenticationFlow(val flow: Flow) :
SmsAuthentication,
Flow by flow
{
override fun auth() {
// you can use flow as this here
}
}
fun doAuth(flow: Flow) {
DefaultSmsAuthenticationFlow(flow).auth()
}