Julian Rubin
Julian Rubin

Reputation: 1235

Kotlin class delegation, passing this to delegate

Is there any possibility to pass this when delegating class in kotlin?

class SomeFlow : Flow, SmsAuthentication by DefaultSmsAuthentication(this)

It says this does not exist in this context. The other class looks like this:

class DefaultSmsAuthentication(val flow: Flow) : SmsAuthentication

Upvotes: 16

Views: 3032

Answers (1)

AngryCodingBird
AngryCodingBird

Reputation: 408

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()
}

Upvotes: 17

Related Questions