Dagger Class Inject
Preface
For the majority of Dagger users, you don't exactly need this library. Simply provision your Java Class
object in a @Provider
method in a valid Dagger @Module
and call it a day e.g.
@Module
public interface SomeModule {
@Provider
static Class<SomeTool> providesSomeToolClass(){
return SomeTool.class;
}
}
However, if you've been doing constructor injection as a good DI citizen, you probably start hating yourself when the need arise when you want to inject these across your project. Normally, having a few of them is fine. However, once it began to balloon up as per your project complexity, you'll probably start looking for a solution to eliminate the tedium. Hence, this library is born.
Usage
Gradle:
repositories {
mavenCentral()
}
dependencies {
implementation 'com.redconfig:class-inject-api:0.3.1'
annotationProcessor 'com.redconfig:class-inject-processor:0.3.1' //or kapt for Kotlin
//You also need Dagger 2.26 at least
}
Declaration site:
package com.awesomepackage.deep.nested;
@ClassInject
public class SomeTool { ... }
package com.awesomepackage;
@ClassInjectOrigin
public class SomeApp { ... }
After building your project once, depend upon the generated ClassProvidersModule
in your main component:
package com.awesomepackage;
@Component(modules = {
ClassProvidersModule.class //generated by the library in whichever package @ClassInjectOrigin was found
})
public interface SomeAppComponent { ... }
Finally, in your injection sites:
package com.awesomepackage.deep.nested;
public class SomeGenericTool {
@Inject
public SomeGenericTool(Class<SomeTool> someToolClass){ //tada!
...
}
public SomeTool doSomethingWithClass(){
return parseSomething(someToolClass);
}
}
This library automatically generate valid Dagger Class
providers for Java classes annotated with @ClassInject
. These providers are then written into Dagger modules aptly named as GeneratedClassProvidersModule
, which are all graphed into the "root" module, ClassProvidersModule
.
Root modules are created in the package where @ClassInjectOrigin
was annotated.
Advanced Configuration
By default, the processor works in modular
mode which produces GeneratedClassProviderModule
in the packages where @ClassInject
is found. This is necessary to support classes with package local visibility. In certain projects, this may generate a lot of modules and may not be the behavior you want.
To alleviate this, the library also provides a monolith
mode. This mode massively cuts down the size of generated modules and it simply provisions the class directly in the root modules instead. Note that this mode only works if all of your @ClassInject
classes visibility are public
.
You can enable monolith
mode by passing the argument below to the compiler arguments:
com.redconfig.classinject.mode=monolith
e.g. for Java projects with Gradle:
compileJava {
options.compilerArgs += '-Acom.redconfig.classinject.mode=monolith'
}
Hilt Support
As of 0.3.1
, Dagger Hilt is supported via compiler arguments:
//Apply Hilt plugin as per Hilt docs. Then:
android {
...
defaultConfig {
applicationId ...
minSdkVersion ...
targetSdkVersion ...
javaCompileOptions {
annotationProcessorOptions {
arguments += ['com.redconfig.classinject.module_annotations':"hilt"]
arguments += ['com.redconfig.classinject.mode':"monolith"] //optional
}
}
}
}
@ClassInjectOrigin
@HiltAndroidApp
public class MyApplication extends Application {
...
}
@ClassInject
public class SomeClass {
...
}
It is much simpler as Hilt has taken most of the module wiring on its own.
The generated modules are installed in SingletonComponent. Hilt itself is not included in this library, hence you need to declare them separately.
Known Issues
The library was made with Dagger 2.29.1
. It is however possible to encounter a compilation error on versions below 2.26
due to Dagger missing some annotations. If you encounter such issue, please upgrade to the latest Dagger library.
License
This library is provided under Apache 2.0