My simple KSP processor that generates dagger modules with multibindings
repositories {
maven { url = uri("https://oss.sonatype.org/content/repositories/releases/") }
}
dependencies {
implementation("ru.fredboy:automultibind-annotations:1.0.4")
ksp("ru.fredboy:automultibind-ksp:1.0.4")
}
For usage example see sample module
Instead of manually writing:
@Module
abstract class MyInterfaceIntoSetModule {
@Binds @IntoSet
abstract fun bindMyImplementation1(impl: MyImplementation1): IMyInterface
@Binds @IntoSet
abstract fun bindMyImplementation2(impl: MyImplementation2): IMyInterface
}You can simply annotate your implementations:
@BindMyInterfaceIntoSet
@BindMyInterfaceIntoMap(stringKey = MyImplementation1.KEY)
class MyImplementation1 @Inject constructor() : IMyInterface {
override fun getString() = "My implementation #1"
companion object {
const val KEY = "MyImplementation1_Key"
}
}The processor scans for these annotations and generates all the necessary Dagger modules.
interface IMyInterface {
fun getString(): String
}For example, for IntoSet bindings:
@BindsIntoSet(
interfaceClass = IMyInterface::class,
modulePackage = AutomultibindConfig.MODULE_PACKAGE,
moduleName = "MyInterfaceIntoSetModule"
)
annotation class BindMyInterfaceIntoSetFor IntoMap bindings with StringKey:
@BindsIntoMapStringKey(
interfaceClass = IMyInterface::class,
modulePackage = AutomultibindConfig.MODULE_PACKAGE,
moduleName = "MyInterfaceIntoMapModule"
)
annotation class BindMyInterfaceIntoMap(val stringKey: String)@BindMyInterfaceIntoSet
@BindMyInterfaceIntoMap(stringKey = MyImplementation2.KEY)
class MyImplementation2 @Inject constructor() : IMyInterface {
override fun getString() = "My implementation #2"
companion object {
const val KEY = "MyImplementation2_Key"
}
}The processor will generate modules like:
@Module
@Generated(value = ["ru.fredboy.automultibind.processor.BindsIntoSetSymbolProcessor"])
abstract class MyInterfaceIntoSetModule {
@Binds @IntoSet
abstract fun bindMyImplementation1(impl: MyImplementation1): IMyInterface
@Binds @IntoSet
abstract fun bindMyImplementation2(impl: MyImplementation2): IMyInterface
}@Module
@Generated(value = ["ru.fredboy.automultibind.processor.BindsIntoMapStringKeySymbolProcessor"])
abstract class MyInterfaceIntoMapModule {
@Binds @IntoMap @StringKey("MyImplementation1_Key")
abstract fun bindMyImplementation1(impl: MyImplementation1): IMyInterface
@Binds @IntoMap @StringKey("MyImplementation2_Key")
abstract fun bindMyImplementation2(impl: MyImplementation2): IMyInterface
}Then you just include them in your Dagger component:
@Component(
modules = [
MyInterfaceIntoSetModule::class,
MyInterfaceIntoMapModule::class
]
)
interface MyComponent {
fun getMyClass(): MyClass
}- Zero boilerplate: Just annotate your implementation, and modules are generated.
- Type-safe: Module signatures are generated based on your actual types.
- Consistent: All modules follow the same style and conventions.
- Flexible: Works for both
IntoSetandIntoMapbindings (string keys).