You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
abstractclassKotlinModule : AbstractModule() {
overridefunbinder() =super.binder().skipSources(KotlinModule::class.java) // <-- Here I configure binder to ignore KotlinModule classprotectedinlinefun <reifiedT : Any> bind() = bind(typeLiteral<T>())
protectedinlinefun <reifiedT : 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.
abstractclassKotlinPrivateModule : PrivateModule() {
overridefunbinder() =// <-- this does not compile since binder() is final in PrivateModulesuper.binder().skipSources(KotlinModule::class.java)
protectedinlinefun <reifiedT : 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.
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>())...
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1525>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGBRXJJYZSBSB4JUE3YZMTTTHBUDANCNFSM463KEEFA>
.
What about using extension methods instead of subclassing?
@ronshapiro , extension methods cannot use protected APIs
inlinefun <reifiedT : Any> AbstractModule.bind() =
bind(typeLiteral<T>()) // <-- error here: Cannot access 'bind': it is protected in 'AbstractModule'
Unfortunately, all Guice methods are declared as protected, so there's no way to extend it without subclassing.
Frankly speaking, I would love to make methods public rather than protected (e.g. extract interfaces for PrivateModule, AbstractModule) , however, that is probably, another issue.
Activity
ronshapiro commentedon Jun 17, 2021
vlsi commentedon Jun 17, 2021
@ronshapiro , extension methods cannot use protected APIs
Unfortunately, all Guice methods are declared as
protected, so there's no way to extend it without subclassing.Frankly speaking, I would love to make methods public rather than protected (e.g. extract interfaces for
PrivateModule,AbstractModule) , however, that is probably, another issue.Make PrivateModule#binder() non-final to allow binder customization i…
Make PrivateModule#binder() non-final to allow binder customization i…