Skip to content

Dagger ‐ Scoping using component factory

Devrath edited this page Oct 8, 2023 · 10 revisions

Observations

Output

// ------> When the activity is loaded for the first time and we create the component
Injected
Custom retrofit initiate method is invoked!
serializer INSTANCE -> 108448087
networkCore INSTANCE -> 37121092
analyticsService INSTANCE- > 113312045
Analytics service has tracked your action:-> RETROFIT
retrofit INSTANCE- > 72836706
Retrofit called
// ------> We rotate the device and recreate the same component for the second time
Injected
Custom retrofit initiate method is invoked!
serializer INSTANCE -> 135361086
networkCore INSTANCE -> 170965151
analyticsService INSTANCE- > 113312045
Analytics service has tracked your action:-> RETROFIT
retrofit INSTANCE- > 150552044
Retrofit called
// ------> Now we just recreate the component for the third time
Injected
Custom retrofit initiate method is invoked!
serializer INSTANCE -> 135361086
networkCore INSTANCE -> 170965151
analyticsService INSTANCE- > 113312045
Analytics service has tracked your action:-> RETROFIT
retrofit INSTANCE- > 150552044
Retrofit called

Code

Scopes

ActivityScope.kt

@Scope
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class ActivityScope

Implementations

Logger.kt

interface Logger {
    fun print(message:String)
}

CustomLogger.kt

class CustomLogger @Inject constructor() : Logger{
    override fun print(message: String) {
        PrintUtils.printLog(message)
    }
}

TimberLogger.kt

class TimberLogger {
    fun print(message: String) {
        PrintUtils.printLog(message)
    }
}

CustomGson.kt

class CustomGson @Inject constructor() {
    init { PrintUtils.printLog("CustomGson class invoked") }
}

CustomOkHttp.kt

class CustomOkHttp @Inject constructor(){
    init { PrintUtils.printLog("CustomOkHttp class invoked") }
}

CustomRetrofit.kt

@ActivityScope
class CustomRetrofit @Inject constructor(
    private val serializer : CustomGson,
    private val networkCore : CustomOkHttp,
    private val analyticsService: AnalyticsService
){
    fun initiateRetrofit() {
        PrintUtils.printLog("Custom retrofit initiate method is invoked!")
        PrintUtils.printLog("serializer INSTANCE -> ${serializer.hashCode()}")
        PrintUtils.printLog("networkCore INSTANCE -> ${networkCore.hashCode()}")
        PrintUtils.printLog("analyticsService INSTANCE- > ${analyticsService.hashCode()}")
        analyticsService.trackEvent("RETROFIT")
    }
}

Modules

CustomLoggerModule.kt

@Module
@DisableInstallInCheck
abstract class CustomLoggerModule {
    @Binds
    abstract fun provideTimberLogger(logger : CustomLogger): Logger

}

CustomRetrofitModule.kt

@Module
@DisableInstallInCheck
class CustomRetrofitModule {
    @ActivityScope
    @Provides
    fun providesRetrofit(
        serializer : CustomGson, networkCore : CustomOkHttp,
        analyticsService: AnalyticsService
    ) : CustomRetrofit {
        return CustomRetrofit(serializer,networkCore,analyticsService)
    }
}

TimberLoggerModule.kt

@Module
@DisableInstallInCheck
class TimberLoggerModule {
    @Provides
    fun provideTimberLogger(): TimberLogger{
        return TimberLogger()
    }
}

Components

NetworkComponent.kt

@ActivityScope
@Component(
    dependencies = [ApplicationComponent::class],
    modules = [
        CustomRetrofitModule::class,
        TimberLoggerModule::class,
        CustomLoggerModule::class
    ]
)
interface NetworkComponent {

    fun inject(activity : CustomScopeActivity)

    @Component.Factory
    interface Factory {
        fun create(
            applicationComponent: ApplicationComponent
        ) : NetworkComponent
    }

}

Application

DiApplication.kt

@HiltAndroidApp
class DiApplication : Application() {

    private lateinit var connComp : ConnectionComponent

    override fun onCreate() {
        super.onCreate()
        connComp = DaggerConnectionComponent.builder().build()
    }

    fun provideApplicationComponent(): ApplicationComponent { return appComponent }
}

Activity

MyActivity.kt

class CustomScopeActivity : AppCompatActivity() {

    private lateinit var binding: ActivityCustomScopeBinding

    @Inject lateinit var retrofit : CustomRetrofit

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityCustomScopeBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setOnClickListeners();

        val component = DaggerNetworkComponent.factory()
            .create((application as DiApplication).provideApplicationComponent())
            .inject(this@CustomScopeActivity)
    }

    private fun setOnClickListeners() {
        binding.apply {
            initiateUsingComponentBuilderId.setOnClickListener {
                PrintUtils.printLog("Injected")
                retrofit.initiateRetrofit()
                PrintUtils.printLog("retrofit INSTANCE- > ${retrofit.hashCode()}")
                PrintUtils.printLog("Retrofit called")
            }
        }
    }
}
Clone this wiki locally