0
votes

I have the following class, which basically gets a JSON string from AWS, then converts it to an instance of a data class...

class SecretsManager(region: String) {
    private val gson = Gson()
    private val smClient = AWSSecretsManagerClientBuilder.standard().withRegion(region).build()

    fun <T> getSecret(id: String): T {
        val req = GetSecretValueRequest().withSecretId(id)
        val json = smClient.getSecretValue(req).getSecretString()
        return gson.fromJson(json, T::class.java)
    }
}

To be used like this...

val myInstance = SecretsManager("eu-west-2").getSecret<MyDataClass>("myId")

Currently, I get an error - Cannot use 'T' as reified type parameter. I can get around this by marking the function as inline and T as reified , but then I can't access the private attributes from within the function.

What's the best way to do this in Kotlin?

1
You can't access the class of a type parameter, since they're erased. If you don't want to make T reified, accept a Class<T> as a parameteruser
add Class parameter to current function fun <T> getSecret(id: String, clazz: Class<T>): T and create overloaded function inline fun <reified T> getSecret(id: String): T = getSecret(id: String, T::class.java)IR42

1 Answers

1
votes

You need to add another parameter to the getSecret method, and also need to add an inline reified method for that to work. See the code below

class SecretsManager(region: String) {
    private val gson = Gson()
    private val smClient = AWSSecretsManagerClientBuilder.standard().withRegion(region).build()

    fun <T> getSecret(type: Class<T>, id: String): T {
        val req = GetSecretValueRequest().withSecretId(id)
        val json = smClient.getSecretValue(req).getSecretString()
        return gson.fromJson(json, type)
    }

    inline fun <reified T> getSecret(id: String): T = getSecret(T::class.java, id)
}