Description
openedon Jun 17, 2021
Use case: I want to add convenience methods to AbstractModule
and PrivateModule
(for easier Kotlin interop), and the issue is that most of the methods in *Module
are protected
, so the only way to add convenience methods for me is to subclass AbstractModule
and PrivateModule
.
However, the sub-classes are purely technical (abstract class KotlinModule : AbstractModule
and abstract class KotlinPrivateModule : PrivateModule
), so I want to exclude them from "source stack" so the exceptions point to the actual binder use rather than to the common KotlinModule
and KotlinPrivateModule
.
Here's what I do with AbstractModule
, and it more-or-less works:
abstract class KotlinModule : AbstractModule() {
override fun binder() =
super.binder().skipSources(KotlinModule::class.java) // <-- Here I configure binder to ignore KotlinModule class
protected inline fun <reified T : Any> bind() = bind(typeLiteral<T>())
protected inline fun <reified T : Any> bind(name: String) =
bind<T>().annotatedWith(Names.named(name))
...
The good part is that all default AbstractModule
methods like bind(TypeLiteral<T> typeLiteral)
use binder()
method, so they use the overridden binder()
, so all bindings get my skipSources
configuration.
Unfortunately, that does not work for PrivateModule
since binder()
is final there.
abstract class KotlinPrivateModule : PrivateModule() {
override fun binder() = // <-- this does not compile since binder() is final in PrivateModule
super.binder().skipSources(KotlinModule::class.java)
protected inline fun <reified T : Any> bind() = bind(typeLiteral<T>())
...
An alternative option is to make default bind(..)
methods public, so Kotlin/Scala extensions could be added without subclassing AbstractModule
.