Dagger Class Inject

Class level injection support for Dagger

License

License

Categories

Categories

config Application Layer Libs Configuration
GroupId

GroupId

com.redconfig
ArtifactId

ArtifactId

class-inject-api
Last Version

Last Version

0.3.1
Release Date

Release Date

Type

Type

pom.sha512
Description

Description

Dagger Class Inject
Class level injection support for Dagger
Project URL

Project URL

https://github.com/amirulzin/dagger-class-inject
Source Code Management

Source Code Management

https://github.com/amirulzin/dagger-class-inject.git

Download class-inject-api

Dependencies

There are no dependencies for this project. It is a standalone project that does not depend on any other jars.

Project Modules

There are no modules declared in this project.

Version License

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

Versions

Version
0.3.1