It is very connivent to use any DI framework when all the objects required are available in application. For example, I have two classes Logger
, Service
and class Middleware
is dependent on these classes.
class Logger()
class Service()
//this class requires Logger & Service object
class Middleware(private val logger:Logger. private val service:Service)
// middleware object
val middleware = Middleware(Logger(),Service())
Dagger
can build objects of Logger
and Service
classes by indicating @Inject
annotation to all three classes
internal class Logger @Inject constructor()
internal class Service @Inject constructor()
//this class requires Logger & Service object
internal class Middleware @Inject constructor(private val logger:Logger. private val service:Service)
@Component
interface MiddlewareComponent {
fun buildComponent():Middleware
}
// middleware object
val middleware = DaggerMiddlewareComponent.builder().build().buildComponent()
If the project requirements are modified to get Logger
with custom implementation, we can write @Module
to support dependency injection.
// now, Logger is interface
interface Logger
class Service @Inject constructor()
class Middleware @Inject constructor(val logger: Logger, val service: Service)
@Module
class LoggerModule constructor(val logger: Logger) {
@Provides
fun providesLogger(): Logger {
return logger
}
}
@Component(modules = [LoggerModule::class])
interface MiddlewareComponent {
fun buildComponent(): Middleware
}
//custom implementation
class NullLogger : Logger
//injecting logger module with interface implementation
val middleware = DaggerMiddlewareComponent.builder().loggerModule(LoggerModule(NullLogger())).build().buildComponent()