SlideShare uma empresa Scribd logo
1 de 91
Baixar para ler offline
Using Hilt in a
modularized project
Fabio Collini
@fabioCollini
Dependency Injection
Vs
Service Locator
class MyClass {

private val collaborator2 = Collaborator2()

fun execute() {

val value = Collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
Plaincode
class MyClass(serviceLocator: ServiceLocator) {

private val collaborator1 = serviceLocator.collaborator1

private val collaborator2 = serviceLocator.collaborator2

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
ServiceLocator
class MyClass(

private val collaborator1: Collaborator1,

private val collaborator2: Collaborator2

) {

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
DependencyInjection
class MyClass(

private val collaborator1: Collaborator1,

private val collaborator2: Collaborator2

) {

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
class MyClass(serviceLocator: ServiceLocator) {

private val collaborator1 = serviceLocator.collaborator1

private val collaborator2 = serviceLocator.collaborator2

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
ServiceLocatorDependencyInjection
Dependencies are
retrieved using the
Service Locator
Dependencies are
injected by the
container
Dagger is a Dependency Injection framework
But a Dagger component can be used as a Service Locator
Is Dagger a Dependency Injection framework?
What about Hilt?
WhatIcareabout
Dependency Injection on classes we can instantiate
Easy setup on classes instantiated by the framework
Testability
Objects
definition
Dagger&Hilt
The same syntax can be
used to define objects using
both Dagger and Hilt
class MyRepository(

private val api: Api

) {

fun loadData() = api.load()

}
class MyRepository @Inject constructor(

private val api: Api

) {

fun loadData() = api.load()

}
@Singleton

class MyRepository @Inject constructor(

private val api: Api

) {

fun loadData() = api.load()

}
Retrofit.Builder()

.baseUrl("""...")

!//!!...

.build()

.create(Api"::class.java)
@Provides

@Singleton

fun provideApi(): Api {

return Retrofit.Builder()

.baseUrl("""...")

!//!!...

.build()

.create(Api"::class.java)

}
@Module

object MyModule {

@Provides

@Singleton

fun provideApi(): Api {

return Retrofit.Builder()

.baseUrl("""...")

!//!!...

.build()

.create(Api"::class.java)

}

}
Using an object
instead of a class
Dagger generates
less code
@Singleton

class MyRepository @Inject constructor(

private val api: Api

) {

fun loadData() = api.load()

}
@Singleton

class MyRepository @Inject constructor(

private val cache: Cache,

private val api: Api

) {

fun loadData() = cache.load() "?: api.load()

}
interface MyRepository {

fun loadData(): Any

}

@Singleton

class MyRepositoryImpl @Inject constructor(

private val cache: Cache,

private val api: Api

) : MyRepository {

override fun loadData() = cache.load() "?: api.load()

}1
interface MyRepository {

fun loadData(): Any

}

@Singleton

class MyRepositoryImpl @Inject constructor(

private val cache: Cache,

private val api: Api

) : MyRepository {

override fun loadData() = cache.load() "?: api.load()

}1

@Module

interface AnotherModule {

@Binds

fun MyRepositoryImpl.bindsRepository(): MyRepository

}
Hilt
@InstallIn

@AndroidEntryPoint

@ViewModelInject

@HiltAndroidApp

@EntryPoint
Newannotations
@Module

object MyModule {

!//!!...

}
@Module

@InstallIn(SingletonComponent"::class)

object MyModule {

!//!!...

}
@Module

@InstallIn(SingletonComponent"::class)

object OkHttpConfigModule {

@Provides

@ElementsIntoSet

fun provideDefaultInterceptors(): Set<Interceptor> = emptySet()

@Singleton

@Provides

fun providesOkHttpClient(

interceptors: @JvmSuppressWildcards Set<Interceptor>

): OkHttpClient {

val httpClient = OkHttpClient.Builder()

interceptors.forEach {

httpClient.addInterceptor(it)

}

return httpClient.build()

}1

}2
src/main
@Module

@InstallIn(SingletonComponent"::class)

object OkHttpConfigModule {

@Provides

@ElementsIntoSet

fun provideDefaultInterceptors(): Set<Interceptor> = emptySet()

@Singleton

@Provides

fun providesOkHttpClient(

interceptors: @JvmSuppressWildcards Set<Interceptor>

): OkHttpClient {

val httpClient = OkHttpClient.Builder()

interceptors.forEach {

httpClient.addInterceptor(it)

}

return httpClient.build()

}1

}2

@Module

@InstallIn(SingletonComponent"::class)

object DebugOkHttpConfigModule {

@Provides

@IntoSet

fun provideDebugInterceptor(): Interceptor = HttpLoggingInterceptor()

}
src/mainsrc/debug
class MainActivity : AppCompatActivity() {

@Inject

lateinit var permissionManager: PermissionManager

@Inject

lateinit var mainNavigator: MainNavigator

!//!!...

}
@AndroidEntryPoint

class MainActivity : AppCompatActivity() {

@Inject

lateinit var permissionManager: PermissionManager

@Inject

lateinit var mainNavigator: MainNavigator

!//!!...

}
@AndroidEntryPoint

class MainActivity : AppCompatActivity() {

@Inject

lateinit var permissionManager: PermissionManager

@Inject

lateinit var mainNavigator: MainNavigator

!//!!...

}
@AndroidEntryPoint

class MainActivity : AppCompatActivity() {

private val viewModel: MyViewModel by viewModels()

@Inject

lateinit var permissionManager: PermissionManager

@Inject

lateinit var mainNavigator: MainNavigator

!//!!...

}
class MyViewModel @ViewModelInject constructor(

private val useCase: MyUseCase

) : ViewModel() {

!//!!...

}
class MyViewModel @ViewModelInject constructor(

private val useCase: MyUseCase,

@Assisted private val handle: SavedStateHandle

) : ViewModel() {

!//!!...

}
class MyViewModel @ViewModelInject constructor(

private val useCase: MyUseCase,

@Assisted private val handle: SavedStateHandle

) : ViewModel() {

init {

load(handle.get<String>("Id"))

}

!//!!...

}
class MyApp : Application() {

@Inject

lateinit var dependency: Dependency

!//!!...

}
@HiltAndroidApp

class MyApp : Application() {

@Inject

lateinit var dependency: Dependency

!//!!...

}
No more components!
(sort of…)
@Component(

modules = {

"//""...

}

)

@Singleton

public abstract static class SingletonC implements SingletonComponent,

"//…

{

}

@Subcomponent(

modules = {

"//""...

}

)

@ActivityScoped

public abstract static class ActivityC implements ActivityComponent,

"//""...

{

@Subcomponent.Builder

abstract interface Builder extends ActivityComponentBuilder {

}

}
!!/**

* A generated base class to be extended by the @dagger.hilt.android.AndroidEntryPoint annotated class.

* If using the Gradle plugin, this is swapped as the base class via bytecode transformation.

!*/

public abstract class Hilt_MainActivity extends AppCompatActivity

implements GeneratedComponentManagerHolder {

"//""...

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

((MainActivity_GeneratedInjector) this.generatedComponent())

.injectMainActivity(UnsafeCasts.<MainActivity>unsafeCast(this));

super.onCreate(savedInstanceState);

}

"//""...

}
!!/**

* A generated base class to be extended by the @dagger.hilt.android.AndroidEntryPoint annotated class.

* If using the Gradle plugin, this is swapped as the base class via bytecode transformation.

!*/

public abstract class Hilt_MainActivity extends AppCompatActivity

implements GeneratedComponentManagerHolder {

"//""...

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

((MainActivity_GeneratedInjector) this.generatedComponent())

.injectMainActivity(UnsafeCasts.<MainActivity>unsafeCast(this));

super.onCreate(savedInstanceState);

}

"//""...

}
!!/**

* A generated base class to be extended by the @dagger.hilt.android.AndroidEntryPoint annotated class.

* If using the Gradle plugin, this is swapped as the base class via bytecode transformation.

!*/

public abstract class Hilt_MainActivity extends AppCompatActivity

implements GeneratedComponentManagerHolder {

"//""...

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

((MainActivity_GeneratedInjector) this.generatedComponent())

.injectMainActivity(UnsafeCasts.<MainActivity>unsafeCast(this));

super.onCreate(savedInstanceState);

}

"//""...

}
MonolithicComponent
Simple
sometimes you need an extra Qualifier annotation
Less generated code
Everything can be injected everywhere
internal can be useful to limit the scope
@EntryPoint

@InstallIn(SingletonComponent"::class)

interface MyEntryPoint {

val myUseCase: MyUseCase



fun inject(something: Something)

}
@EntryPoint

@InstallIn(SingletonComponent"::class)

interface MyEntryPoint {

val myUseCase: MyUseCase



fun inject(something: Something)

}

val entryPoint = EntryPointAccessors.fromApplication(

app, MyEntryPoint"::class.java)

val useCase = entryPoint.myUseCase
Testing
class MyClass @Inject constructor(

private val collaborator1: Collaborator1,

private val collaborator2: Collaborator2

) {

fun execute() {

val value = collaborator1.loadSomething()

collaborator2.doSomethingElse(value)

}

}
class MyClassTest {

private val collaborator1 = mock<Collaborator1>()

private val collaborator2 = mock<Collaborator2>()

private val myObject = MyClass(collaborator1, collaborator2)

@Test

fun testSomething() {

whenever(collaborator1.loadSomething()) doReturn "something"

myObject.execute()

verify(collaborator2).doSomethingElse("something")

}

}
@Singleton

open class MyAnalytics @Inject constructor()

interface MyUseCase

@Singleton

class MyUseCaseImpl @Inject constructor() : MyUseCase

@Module

@InstallIn(SingletonComponent"::class)

interface MyModule {

@Binds

fun MyUseCaseImpl.bindsUseCase(): MyUseCase

}

@AndroidEntryPoint

class MyActivity : AppCompatActivity() {

@Inject

lateinit var analytics: MyAnalytics

@Inject

lateinit var useCase: MyUseCase

!//!!...

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@Inject

lateinit var analytics: MyAnalytics

@Inject

lateinit var useCase: MyUseCase

@Test

fun startActivity() {

rule.launchActivity(null)

hiltRule.inject()

!//now the properties contain the production objects

}

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
@Module

@InstallIn(SingletonComponent"::class)

object FakeAnalyticsModule {

@Provides

fun provideAnalytics(): MyAnalytics = mock()

}

@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule1

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@Module

@InstallIn(SingletonComponent"::class)

object FakeAnalyticsModule {

@Provides

fun provideAnalytics(): MyAnalytics = mock()

}

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@BindValue

@JvmField

val analytics: MyAnalytics = mock()

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
@HiltAndroidTest

class MyActivityTest {

@get:Rule

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@BindValue

@JvmField

val useCase: MyUseCase = mock()

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
error: [Dagger/DuplicateBindings] MyUseCase is bound multiple times
@HiltAndroidTest

@UninstallModules(MyModule"::class)

class MyActivityTest {

@get:Rule

val hiltRule = HiltAndroidRule(this)

@get:Rule

val rule = ActivityTestRule(MyActivity"::class.java, false, false)

@BindValue

@JvmField

val useCase: MyUseCase = mock()

@Test

fun startActivity() {

rule.launchActivity(null)

!//!!...

}

}
Multi-module
architecture
It works!
feature3feature1 feature2
App
feature3feature1 feature2
AppFeature1App
feature1 feature2
Feature1App
feature3
App
Activity
Repository
Api
UseCase
ViewModel
entitiesentitiesentitiesentities
domain
repository
UI
data source
presenter
Activity
Repository
Api
UseCase
ViewModel
entitiesentitiesentitiesentities
domain
repository
UI
data source
presenter
Activity
Repository
Api
UseCase
ViewModel
RepositoryImplRepositoryUseCase
domain data
UseCase
RepositoryImpl
Repository
domain data
Repository RepositoryImpl
UseCase
Inversion
Of Control
The “I” in S.O.L.I.D.
https://www.youtube.com/watch?v=GlDsfq3xHvo&t=
domain repository
Repository RepositoryImpl
UseCase
@Inject
@Inject
Module
@Binds
Incomplete Hilt config
dynamic
feature3
App
feature1 feature2
@EntryPoint
@Component
Wrappingup
Dependency Injection on classes we can instantiate
@Inject, @Provides and @Binds

Easy setup on classes instantiated by the framework
@AndroidEntryPoint and @HiltAndroidApp
Testability
@HiltAndroidTest and HiltAndroidRule
Hilt is definitely a
Dependency Injection framework
Hilt is definitely a
Dependency Injection framework
(even if you can use an EntryPoint as a Service Locator)
Links&contacts
Hilt documentation
dagger.dev/hilt/
Android Developers - Dependency injection with Hilt
developer.android.com/training/dependency-injection/hilt-android
Android Developers - Hilt testing guide
developer.android.com/training/dependency-injection/hilt-testing
Manuel Vivo - Dagger and Hilt navigation support in Android Studio
medium.com/androiddevelopers/dagger-navigation-support-in-android-studio-49aa5d149ec9
Fabio Collini - Dagger dependencies beyond the basics
proandroiddev.com/dagger-dependencies-beyond-the-basics-53474e48f932
@fabioCollini
linkedin.com/in/fabiocollini
github.com/fabioCollini
medium.com/@fabioCollini
THANKS
FOR YOUR
ATTENTION
QUESTIONS?
@fabioCollini

Mais conteúdo relacionado

Mais procurados

Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot IntroductionJeevesh Pandey
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOPDzmitry Naskou
 
Introducing Async/Await
Introducing Async/AwaitIntroducing Async/Await
Introducing Async/AwaitValeri Karpov
 
Angular - Chapter 5 - Directives
 Angular - Chapter 5 - Directives Angular - Chapter 5 - Directives
Angular - Chapter 5 - DirectivesWebStackAcademy
 
Managing an OSGi Framework with Apache Felix Web Console
Managing an OSGi Framework with  Apache Felix Web ConsoleManaging an OSGi Framework with  Apache Felix Web Console
Managing an OSGi Framework with Apache Felix Web ConsoleFelix Meschberger
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesLauren Yew
 
Dependency injection in Java, from naive to functional
Dependency injection in Java, from naive to functionalDependency injection in Java, from naive to functional
Dependency injection in Java, from naive to functionalMarian Wamsiedel
 
Angular Data Binding
Angular Data BindingAngular Data Binding
Angular Data BindingDuy Khanh
 
Angular - Chapter 4 - Data and Event Handling
 Angular - Chapter 4 - Data and Event Handling Angular - Chapter 4 - Data and Event Handling
Angular - Chapter 4 - Data and Event HandlingWebStackAcademy
 
Flask Introduction - Python Meetup
Flask Introduction - Python MeetupFlask Introduction - Python Meetup
Flask Introduction - Python MeetupAreski Belaid
 
Inversion of Control and Dependency Injection
Inversion of Control and Dependency InjectionInversion of Control and Dependency Injection
Inversion of Control and Dependency InjectionDinesh Sharma
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework Serhat Can
 
JCR, Sling or AEM? Which API should I use and when?
JCR, Sling or AEM? Which API should I use and when?JCR, Sling or AEM? Which API should I use and when?
JCR, Sling or AEM? Which API should I use and when?connectwebex
 
Kotlin for Android Development
Kotlin for Android DevelopmentKotlin for Android Development
Kotlin for Android DevelopmentSpeck&Tech
 
Lets make a better react form
Lets make a better react formLets make a better react form
Lets make a better react formYao Nien Chung
 

Mais procurados (20)

Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot Introduction
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Introducing Async/Await
Introducing Async/AwaitIntroducing Async/Await
Introducing Async/Await
 
Angular - Chapter 5 - Directives
 Angular - Chapter 5 - Directives Angular - Chapter 5 - Directives
Angular - Chapter 5 - Directives
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
Managing an OSGi Framework with Apache Felix Web Console
Managing an OSGi Framework with  Apache Felix Web ConsoleManaging an OSGi Framework with  Apache Felix Web Console
Managing an OSGi Framework with Apache Felix Web Console
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
 
Dependency injection in Java, from naive to functional
Dependency injection in Java, from naive to functionalDependency injection in Java, from naive to functional
Dependency injection in Java, from naive to functional
 
Angular Data Binding
Angular Data BindingAngular Data Binding
Angular Data Binding
 
Angular - Chapter 4 - Data and Event Handling
 Angular - Chapter 4 - Data and Event Handling Angular - Chapter 4 - Data and Event Handling
Angular - Chapter 4 - Data and Event Handling
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Flask Introduction - Python Meetup
Flask Introduction - Python MeetupFlask Introduction - Python Meetup
Flask Introduction - Python Meetup
 
Inversion of Control and Dependency Injection
Inversion of Control and Dependency InjectionInversion of Control and Dependency Injection
Inversion of Control and Dependency Injection
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
JCR, Sling or AEM? Which API should I use and when?
JCR, Sling or AEM? Which API should I use and when?JCR, Sling or AEM? Which API should I use and when?
JCR, Sling or AEM? Which API should I use and when?
 
Kotlin for Android Development
Kotlin for Android DevelopmentKotlin for Android Development
Kotlin for Android Development
 
Lets make a better react form
Lets make a better react formLets make a better react form
Lets make a better react form
 

Semelhante a Using hilt in a modularized project

Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFSharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFPierre-Yves Ricau
 
Maintaining a dependency graph with weaver
Maintaining a dependency graph with weaverMaintaining a dependency graph with weaver
Maintaining a dependency graph with weaverScribd
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDiego Lewin
 
Kotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyKotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyMobileAcademy
 
Android architecture
Android architecture Android architecture
Android architecture Trong-An Bui
 
Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Omar Miatello
 
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014First Tuesday Bergen
 
Dagger 2 vs koin
Dagger 2 vs koinDagger 2 vs koin
Dagger 2 vs koinJintin Lin
 
Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02rhemsolutions
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 KotlinVMware Tanzu
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...DicodingEvent
 
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonMastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonAEM HUB
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling RewriterJustin Edelson
 
Say bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & KotlinSay bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & KotlinMiquel Beltran Febrer
 

Semelhante a Using hilt in a modularized project (20)

Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SFSharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SF
 
Hilt Annotations
Hilt AnnotationsHilt Annotations
Hilt Annotations
 
Maintaining a dependency graph with weaver
Maintaining a dependency graph with weaverMaintaining a dependency graph with weaver
Maintaining a dependency graph with weaver
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony Container
 
Kotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyKotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRready
 
Android architecture
Android architecture Android architecture
Android architecture
 
Di code steps
Di code stepsDi code steps
Di code steps
 
Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01Android & Kotlin - The code awakens #01
Android & Kotlin - The code awakens #01
 
Dependency Injection for Android
Dependency Injection for AndroidDependency Injection for Android
Dependency Injection for Android
 
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
 
Dagger 2 vs koin
Dagger 2 vs koinDagger 2 vs koin
Dagger 2 vs koin
 
Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02Architecting your GWT applications with GWT-Platform - Lesson 02
Architecting your GWT applications with GWT-Platform - Lesson 02
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 Kotlin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
 
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonMastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin Edelson
 
Mastering the Sling Rewriter
Mastering the Sling RewriterMastering the Sling Rewriter
Mastering the Sling Rewriter
 
Say bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & KotlinSay bye to Fragments with Conductor & Kotlin
Say bye to Fragments with Conductor & Kotlin
 

Mais de Fabio Collini

Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose worldFabio Collini
 
Managing parallelism using coroutines
Managing parallelism using coroutinesManaging parallelism using coroutines
Managing parallelism using coroutinesFabio Collini
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confFabio Collini
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmFabio Collini
 
Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectFabio Collini
 
Solid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalySolid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalyFabio Collini
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaFabio Collini
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureFabio Collini
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFabio Collini
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinFabio Collini
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018Fabio Collini
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFabio Collini
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFabio Collini
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKFabio Collini
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Fabio Collini
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaFabio Collini
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKFabio Collini
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternFabio Collini
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeFabio Collini
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMFabio Collini
 

Mais de Fabio Collini (20)

Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 
Managing parallelism using coroutines
Managing parallelism using coroutinesManaging parallelism using coroutines
Managing parallelism using coroutines
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community conf
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
 
Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture project
 
Solid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalySolid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon Italy
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UK
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 

Último

%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 

Último (20)

%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 

Using hilt in a modularized project