Slide 1

Slide 1 text

@Inject Basics ! Jitin Sharma GO-JEK @_jitinsharma

Slide 2

Slide 2 text

Dagger!

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

@Provides @Inject @Module @Component @Named @Singleton @Qaulifier @BindsInstance HasActivityInjector AndroidInjection @Subcomponent @ContributesAndroidInjector

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Dependency Injection What and Why @_jitinsharma

Slide 8

Slide 8 text

Dependency injection is a technique whereby one object supplies the dependencies of another object

Slide 9

Slide 9 text

Setter Injection class Jitin { lateinit var stage: Stage fun setStage(stage: Stage) { this.stage = stage } ...

Slide 10

Slide 10 text

Constructor Injection class Jitin(private val stage: Stage) { ...

Slide 11

Slide 11 text

Constructor Injection class Jitin(private val stage: Stage, private var mic: Boolean = true) Jitin(stage = getStage(), mic = false) Jitin(stage = getStage())

Slide 12

Slide 12 text

Android Components - Activity - Application - Services - ...

Slide 13

Slide 13 text

INVERSIOИ OF CONTROL @_jitinsharma

Slide 14

Slide 14 text

DogActivity DogPresenter DogAPI DogRepository DogView

Slide 15

Slide 15 text

DogActivity DogPresenter DogAPI DogRepository DogView Dependencies

Slide 16

Slide 16 text

DogActivity DogPresenter DogAPI DogRepository DogView Dependencies

Slide 17

Slide 17 text

Dependency Container val dogApi: DogApi get() = ApiClient.dogClient.create(DogApi::class.java) val dogRepository get() = DogRepository() val presenter get() = DogPresenter()

Slide 18

Slide 18 text

Dependency Container object DogDependencyContainer { var dogView: DogView? = null fun init(dogView: DogView) { this.dogView = dogView } ... val dogApi: DogApi get() = ApiClient.dogClient.create(DogApi::class.java) val dogRepository get() = DogRepository() val presenter get() = DogPresenter()

Slide 19

Slide 19 text

Dependency Container inline fun inject(): T { return when (T::class) { DogApi::class -> dogApi as T DogPresenter::class -> presenter as T DogRepository::class -> dogRepository as T DogView::class -> dogView as T else -> throw DependencyNotFoundException() } }

Slide 20

Slide 20 text

Dependency Container class DogPresenter { private val dogView by lazy { inject() } private val dogRepository by lazy { inject() } class DogRepository { private val dogApi by lazy { inject() }

Slide 21

Slide 21 text

Dependency Container class DogActivity : AppCompatActivity(), DogView { private val dogPresenter by lazy { inject() } ... override fun onCreate(savedInstanceState: Bundle?) { ... DogDependencyContainer.init(this) ...

Slide 22

Slide 22 text

SERVICE LOCATOR @_jitinsharma

Slide 23

Slide 23 text

DogActivity DogPresenter DogAPI DogRepository DogView DependencyContainer

Slide 24

Slide 24 text

DogActivity DogPresenter DogAPI DogRepository DogView class DogRepository(private val dogApi: DogApi) class DogPresenter(private var dogView: DogView?, private val dogRepository: DogRepository) // Interface DependencyContainer

Slide 25

Slide 25 text

Dependency Container private val dogApi get() = ApiClient.dogClient.create(DogApi::class.java) private val dogRepository get() = DogRepository(dogApi) val presenter get() = DogPresenter(dogView, dogRepository)

Slide 26

Slide 26 text

Dependency Container class DogActivity : AppCompatActivity(), DogView { private val dogPresenter by lazy { inject() } ... override fun onCreate(savedInstanceState: Bundle?) { ... DogDependencyContainer.init(this) ...

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

DAGGER @_jitinsharma

Slide 30

Slide 30 text

@Inject javax.inject (JSR 330)

Slide 31

Slide 31 text

@Inject javax.inject (JSR 330) @Provides @Provides ...

Slide 32

Slide 32 text

@Inject javax.inject (JSR 330) @Provides @Provides ... @Module

Slide 33

Slide 33 text

@Inject javax.inject (JSR 330) @Provides @Provides ... @Module @Component

Slide 34

Slide 34 text

DogActivity DogPresenter DogAPI DogRepository DogView @Provides fun dogView(): DogView = dogView @Provides fun dogApi(): DogApi = ApiClient.dogClient.create(DogApi::class.java)

Slide 35

Slide 35 text

class DogRepository @Inject constructor(private val dogApi: DogApi) class DogPresenter @Inject constructor( private var dogView: DogView?, private val dogRepository: DogRepository ) Injecting Constructors

Slide 36

Slide 36 text

@Component(modules = [DogModule::class]) interface DogComponent { fun inject(mainActivity: MainActivity) } Wiring up dependencies

Slide 37

Slide 37 text

Injecting Dependencies class MainActivity : AppCompatActivity(), DogView { @Inject lateinit var dogPresenter: DogPresenter override fun onCreate(savedInstanceState: Bundle?) { DaggerDogComponent.builder().dogModule(DogModule((this))).build().inject(this) } }

Slide 38

Slide 38 text

public final class DaggerDogComponent implements DogComponent { private DogRepository getDogRepository() { return new DogRepository(DogModule_DogApiFactory.dogApi(dogModule)); } private DogPresenter getDogPresenter() { return new DogPresenter(DogModule_DogViewFactory.dogView(dogModule), getDogRepository()); } ... Component Generation

Slide 39

Slide 39 text

Injection via code generation DaggerDogComponent... ..inject(this) DogActivity DogActivity.kt

Slide 40

Slide 40 text

Injection via code generation DaggerDogComponent... ..inject(this) DogActivity @Override public void inject(DogActivity dogActivity) { injectDogActivity(dogActivity); } DogActivity.kt DaggerCatComponent.java

Slide 41

Slide 41 text

Injection via code generation DaggerDogComponent... ..inject(this) DogActivity @Override public void inject(DogActivity dogActivity) { injectDogActivity(dogActivity); } public static void injectDogPresenter(DogActivity instance, DogPresenter dogPresenter) { instance.dogPresenter = dogPresenter; } DogActivity.kt DaggerCatComponent.java DogActivity_MembersInjector.java

Slide 42

Slide 42 text

Injection via code generation DaggerDogComponent... ..inject(this) DogActivity @Override public void inject(DogActivity dogActivity) { injectDogActivity(dogActivity); } public static void injectDogPresenter(DogActivity instance, DogPresenter dogPresenter) { instance.dogPresenter = dogPresenter; } @Inject lateinit var dogPresenter: DogPresenter DogActivity.kt DaggerCatComponent.java DogActivity_MembersInjector.java

Slide 43

Slide 43 text

Scopes @Singleton @Component(modules = [AppModule::class]) interface AppComponent { ... @DogScope @Component(modules = [DogModule::class], dependencies = [AppComponent::class]) interface DogComponent { ... DogComponent.kt AppComponent.kt

Slide 44

Slide 44 text

DaggerDogComponent.builder() .appComponent(appComponent) .dogModule(DogModule((this))) .build() .inject(this) Inversion of Control

Slide 45

Slide 45 text

DAGGER-ANDROID @_jitinsharma

Slide 46

Slide 46 text

“screams in japanese”

Slide 47

Slide 47 text

“screams in japanese”

Slide 48

Slide 48 text

AndroidInjector Activity Fragment Service BrodcastReceiver ContentProvider Core Components

Slide 49

Slide 49 text

@Module class DogModule { @Provides fun providesDogView(dogActivity: DogActivity): DogView = dogActivity ... @Binds abstract fun provideDogView(dogActivity: DogActivity): DogView

Slide 50

Slide 50 text

@Module abstract class BuildersModule { @ContributesAndroidInjector(modules = [DogModule::class]) abstract fun bindDogActivity(): DogActivity ...

Slide 51

Slide 51 text

@Singleton @Component(modules = [AndroidInjectionModule::class, AppModule::class, BuildersModule::class]) interface AppComponent { @Component.Builder interface Builder { @BindsInstance fun application(application: AnimalApp): Builder fun build(): AppComponent } fun inject(app: AnimalApp)

Slide 52

Slide 52 text

class DogActivity : AppCompatActivity(), DogView { @Inject lateinit var dogPresenter: DogPresenter ... override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) ...

Slide 53

Slide 53 text

AndroidInjection.inject(this) Activity Fragment Service Content Provider Broadcast Receiver

Slide 54

Slide 54 text

Application Activity Fragment Service Content Provider Broadcast Receiver HasActivityInjector HasFragmentInjector HasServiceInjector HasBroadcastReceiverInjector HasContentProviderInjector HasFragmentInjector

Slide 55

Slide 55 text

Application Activity Fragment Service Content Provider Broadcast Receiver HasActivityInjector HasFragmentInjector HasServiceInjector HasBroadcastReceiverInjector HasContentProviderInjector HasFragmentInjector

Slide 56

Slide 56 text

class AnimalApp : Application(), HasActivityInjector { @Inject lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector override fun activityInjector(): AndroidInjector = dispatchingAndroidInjector override fun onCreate() { super.onCreate() DaggerAppComponent.builder() .application(this) .build() .inject(this) ...

Slide 57

Slide 57 text

class AnimalApp : Application(), HasActivityInjector { @Inject lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector override fun activityInjector(): AndroidInjector = dispatchingAndroidInjector override fun onCreate() { super.onCreate() DaggerAppComponent.builder() .application(this) .build() .inject(this) ...

Slide 58

Slide 58 text

class AnimalApp : Application(), HasActivityInjector { @Inject lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector override fun activityInjector(): AndroidInjector = dispatchingAndroidInjector override fun onCreate() { super.onCreate() DaggerAppComponent.builder() .application(this) .build() .inject(this) ...

Slide 59

Slide 59 text

AppComponent Activity Modules Builder Module (@ContributesAndroidInjector) //Generated DaggerAppComponent SubComponent: AndroidInjector<> Provider Map DispatchingAndroidInjector

Slide 60

Slide 60 text

//Generated DaggerAppComponent SubComponent: AndroidInjector<> Provider Map DispatchingAndroidInjector @Inject dispatchingAndroidInjector: DispatchingAndroidInjector Application class Activity Class AndroidInjection.inject(this) @Override public void inject(DogActivity arg0) { injectDogActivity(arg0); }

Slide 61

Slide 61 text

class DogActivity : DaggerAppCompatActivity(), DogView { @Inject lateinit var dogPresenter: DogPresenter ... Support Module

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

KOTLIN @_jitinsharma

Slide 64

Slide 64 text

Kotlin Delegation Lambda DSL

Slide 65

Slide 65 text

KOIN @_jitinsharma

Slide 66

Slide 66 text

• A Dependency Injection Framework for Kotlin • Does not use code generation • Works using Lambdas and Extensions KOIN

Slide 67

Slide 67 text

val catModule = module { single { ApiClient.catClient.create(CatApi::class.java) } single { CatRepository(get()) } factory { (catView: CatView) -> CatPresenter(catView, get()) } } Module Declaration

Slide 68

Slide 68 text

val catModule = module { single { ApiClient.catClient.create(CatApi::class.java) } single { CatRepository(get()) } factory { (catView: CatView) -> CatPresenter(catView, get()) } } Module Declaration

Slide 69

Slide 69 text

Startup Configuration class AnimalApp : Application(){ override fun onCreate() { super.onCreate() startKoin { androidContext(this@AnimalApp) modules(listOf(catModule, dogModule, appModule)) } ...

Slide 70

Slide 70 text

class CatActivity : AppCompatActivity(), CatView { private val catPresenter: CatPresenter by inject { parametersOf(this) } private val imageLoader: ImageLoader by inject() ... Injecting Members

Slide 71

Slide 71 text

Load Modules BeanRegistry HashSet by inject()

Slide 72

Slide 72 text

Load Modules BeanRegistry HashSet by inject() Service Locator

Slide 73

Slide 73 text

Modules and Scopes unloadKoinModules(catModule) loadKoinModules(catModule) // GlobalScope

Slide 74

Slide 74 text

Modules and Scopes scope(named()) { scoped { (catView: CatView) -> CatPresenter(catView, get()) } } CatPresenter by currentScope.inject { ... LifeCycleOwner

Slide 75

Slide 75 text

Modules and Scopes scope(named()) { scoped { (catView: CatView) -> CatPresenter(catView, get()) } } CatPresenter by currentScope.inject { ... LifeCycleOwner

Slide 76

Slide 76 text

Koin has • Easy configuration • Drop in support for Android with ViewModels and Scopes • Excellent documentation and testing support

Slide 77

Slide 77 text

Koin does not have • Strict Compile time safety • Facility of automatic constructors without using reflection

Slide 78

Slide 78 text

Probably Yes Do you need Dependency Injection

Slide 79

Slide 79 text

It Depends Do you need DI frameworks?

Slide 80

Slide 80 text

Before software can be reusable it first has to be usable. Ralph Johnson

Slide 81

Slide 81 text

- Koin - Kodein - Katana … … - RoboGuice - Dagger 1 - Dagger 2 Kotlin

Slide 82

Slide 82 text

• https://jakewharton.com/helping-dagger-help-you/ • https://github.com/handstandsam/ShoppingApp Resources

Slide 83

Slide 83 text

Danke schön @_jitinsharma