Tele Softas Empowering innovation 1 Dagger Android contributions
Tele. Softas - Empowering innovation 1 Dagger + Android contributions Sigitas Atkočaitis
Tele. Softas - Empowering innovation Why Dagger 2
private fun set. Up. Injection() { navigator = Navigator() Tele. Softas - Empowering innovation 2 location. Permission. Manager = Location. Permission. Manager( this) val lat. Lng. Mapper = Lat. Lng. Mapper. Impl() val converter = Bitmap. Descriptor. Converter(resources) val marker. Generator = Marker. Generator. Impl(lat. Lng. Mapper , converter) val adapter = Marker. Info. Window. Adapter(activity!!. layout. Inflater) val cluster. Icon. Provider = Cluster. Icon. Provider. Impl(converter) map = Pharmacies. Map. Holder(marker. Generator , lat. Lng. Mapper, adapter, this, cluster. Icon. Provider) val retriever = Dependency. Retriever. from(context!!) val service = retriever. get. Service(Load. Pharmacies. Service: : class. java) val db. Helper = Dependency. Retriever. from(context!!). database. Helper val pharmacies. Repository = Pharmacies. Repository. Impl(db. Helper) val pref. Repository = Preference. Repository(context!!) val expire. Model = Pharmacies. Expire. Model. Impl(pref. Repository) val pharmacies. Model = Load. Pharmacies. Model. Impl(service , pharmacies. Repository, expire. Model, Schedulers. io()) location. Service = Default. Location. Service(context!!) val model = Pharmacies. Map. Model. Impl(location. Service!! , pharmacies. Model) val resolver = Network. Error. Resolver( Default. Network. Error. Messenger(resources)) presenter = Pharmacies. Map. Presenter. Impl(model , Android. Schedulers. main. Thread() , resolver) }
val storage. Factory = Preference. Storage. Factory() ; Tele. Softas - Empowering innovation val antenna. Storage = storage. Factory. create(context , 2 Antenna: : class); val amplifier. Storage = storage. Factory. create(context , Amplifier: : class); val computation. Scheduler = Schedulers. computation() ; val main. Scheduler = Android. Schedulers. main. Thread() ; val model = Settings. Fragment. Model( val attenuation. Storage = storage. Factory. create(context , Attenuation: : class); band. Region. Repository , val antenna. Repository = Antenna. Repository(antenna. Storage) ; antenna. Repository , val amplifier. Repository = Amplifier. Repository(amplifier. Storage) ; amplifier. Repository , val attenuation. Repository = Attenuation. Repository(attenuation. Storage) ; attenuation. Repository , val band. Region. Storage = storage. Factory. create(context , Band. Region: : class); color. Repository , val color. Range. Storage = storage. Factory. create(context , Color. Range: : class); audio. Tone. Repository , val color. Repository = Color. Repository. Impl(color. Range. Storage) ; form. Provider, val audio. Tone. Storage = storage. Factory. create(context , Audio. Tone: : class); settings. Form. Repository , val audio. Tone. Repository = Audio. Tone. Repository(audio. Tone. Storage) ; val log. Dir. Repository = Session. Dir. Repository. Impl( storage. Factory. create(context , String: : class)); val tile. Dir. Repository = Tiles. Dir. Repository( computation. Scheduler ); val calculator = Auto. Color. Range. Calculator. Impl() ; val selected. List. Storage = storage. Factory. create(context , String: : class)); val form. Storage = storage. Factory. create(context , Band. Region. Holder: : class); val band. Region. List. Repository = storage. Factory. create(context , Settings. Form: : class); Band. Region. List. Repository. Impl(band. Region. Storage , selected. List. Storage , val band. Region. Holder. Storage = storage. Factory. create(context , Band. Region. Holder: : class); band. List. Provider) ; return Settings. Fragment. Presenter( val band. List. Provider = Default. Band. List. Provider() ; model, val band. Region. Repository = calculator, Band. Region. List. Repository. Impl(band. Region. Storage , band. Region. Holder. Storage , band. List. Provider) ; update. Checker, val settings. Form. Repository = Settings. Form. Repository. Impl( Seewave. Application. get. Recorder. Manager(context). get. File. Manager() , antenna. Repository , amplifier. Repository , attenuation. Repository , audio. Tone. Repository , band. Region. Repository , color. Repository , log. Dir. Repository , tile. Dir. Repository , form. Storage ); main. Scheduler, band. Region. List. Repository );
Tele. Softas - Empowering innovation 2 Why Dagger ● ● More Testable Code More Readable Code More Reusable Code Reduced Dependency Carrying
Tele. Softas - Empowering innovation 2 Main Dagger parts ● @Component ● @Sub. Component ● @Module ● @Contributes. Android. Injector
@Dagger. Scope(Base. Application: : class) Tele. Softas - Empowering innovation 2 @Component( modules = [ Android. Support. Injection. Module: : class, App. Module: : class, Activities. Module: : class, Scheduler. Module: : class, Network. Module: : class, Image. Module: : class ] ) interface App. Component : Android. Injector<Base. Application> { @Component. Builder abstract class Builder : Android. Injector. Builder<Base. Application>() } open class Base. Application : Dagger. Application() { override fun application. Injector(): Android. Injector<out Dagger. Application> = Dagger. App. Component. builder(). create(this) }
@Module Tele. Softas - Empowering innovation 2 abstract class App. Module private constructor() { @Binds abstract fun bind. Context(app: Base. Application): Context @Module companion object { @Jvm. Static @Provides fun provide. Resources(context: Context): Resources = context. resources } }
@Module Tele. Softas - Empowering innovation 2 abstract class Scheduler. Module private constructor() { @Module companion object { @Jvm. Static @Provides @Main. Thread fun provide. Main. Scheduler(): Scheduler = Android. Schedulers. main. Thread() @Jvm. Static @Provides @Computation. Thread fun provide. Computation. Scheduler(): Scheduler = Schedulers. computation() @Jvm. Static @Provides @Io. Thread fun provide. Io. Scheduler(): Scheduler = Schedulers. io() @Jvm. Static @Provides @Network. Thread fun provide. Io. Scheduler(): Scheduler = Schedulers. io() } } @Qualifier annotation class Network. Thread
Tele. Softas - Empowering innovation @Module 2 abstract class Image. Module private constructor() { @Binds @Reusable abstract fun bind. Image. Loader(loader: Glide. Image. Loader): Image. Loader }
@Module Tele. Softas innovation abstract- Empowering class Network. Module 2 private constructor() { @Module companion object {. . . @Jvm. Static @Provides @Dagger. Scope(Base. Application: : class) fun provide. Retrofit. Client( @Network. Thread network. Scheduler: Scheduler ): Retrofit = Retrofit. Builder(). add. Call. Adapter. Factory( Rx. Java 2 Call. Adapter. Factory. create. With. Scheduler(network. Scheduler) ). base. Url(Build. Config. API_ENDPOINT). build() } } @Scope annotation class Dagger. Scope (val value: KClass<*>)
Tele. Softas - Empowering innovation @Module 2 abstract class Activities. Module private constructor() { @Dagger. Scope(Main. Activity: : class) @Contributes. Android. Injector(modules = [Main. Activity. Module: : class]) abstract fun bind. Main. Activity(): Main. Activity } class Main. Activity : Dagger. App. Compat. Activity(){. . . }
Tele. Softas - Empowering innovation @dagger. Module 2 abstract class Main. Activity. Module private constructor() { @Dagger. Scope(Main. Fragment: : class) @Contributes. Android. Injector(modules = [Main. Screen. Module: : class]) abstract fun bind. Article. List. Fragment(): Main. Fragment }
object Main. Screen { Tele. Softas - Empowering innovation 2 interface Main. Presenter : Base. Presenter<Main. Screen. View> {. . . } interface View {. . . } @dagger. Module abstract class Module private constructor() { @Binds @Dagger. Scope(Main. Fragment: : class) abstract fun bind. Presenter(presenter: Main. Presenter. Impl): Main. Presenter @dagger. Module companion object { @Provides @Jvm. Static @Dagger. Scope(Main. Fragment: : class) fun provide. Service(retrofit: Retrofit) = retrofit. create<News. Service>() } }
Tele. Softas - Empowering innovation class Main. Presenter. Impl @Inject 2 constructor( private val service: News. Service, @Main. Thread private val scheduler: Scheduler ) : Base. Presenter. Impl<Main. Screen. View>(), Main. Screen. Main. Presenter {. . . } class Main. Fragment : Dagger. Fragment(), Main. Screen. View { @Inject lateinit var presenter: Main. Screen. Main. Presenter override fun on. Create. View(. . . ): View? {. . . presenter. take. View(this) return fragment. View }. . . }
Tele. Softas - Empowering innovation 2 Unit tests You don’t have to use Dagger for single-class unit tests If you want to write a small unit test that tests only one @Injectannotated class, you don’t need to use Dagger to instantiate that class. If you want to write a traditional unit test, you can directly call the @Inject-annotated constructor and methods and set the @Injectannotated fields, if any, passing fake or mock dependencies directly, just as you would if they weren’t annotated. https: //google. github. io/dagger/testing
Tele. Softas - Empowering innovation class Main. Presenter. Impl. Test { 2 private val service = mock<News. Service>() private val view = mock<Main. Screen. View>() private val scheduler = Test. Scheduler() private val presenter = Main. Presenter. Impl(service, scheduler) private val articles = list. Of<Article>(mock()) private val articles. Response = Articles. Response("200", 0, articles) @Test fun example. Unit. Test() { given(service. get. Article. List()). will. Return(Single. just(articles. Response)) presenter. take. View(view) presenter. on. View. Created() scheduler. trigger. Actions() verify(view). show. Articles(articles) }
Tele. Softas - Empowering innovation 2 Instrumentation testing
Tele. Softas - Empowering innovation 2 @Dagger. Scope(Base. Application: : class) @Component( modules = [ Android. Support. Injection. Module: : class, Instrumentation. Module: : class, App. Module: : class, Activities. Module: : class, Instrumentation. Scheduler. Module: : class, Network. Module: : class, Image. Module: : class ] ) interface Test. App. Component : Android. Injector<Test. Base. Application> { @Component. Builder abstract class Builder : Android. Injector. Builder<Test. Base. Application>() }
Tele. Softas - Empowering innovation 2 open class Test. Application. Runner : Android. JUnit. Runner() { @Throws(Exception: : class) override fun new. Application(loader: Class. Loader, class. Name: String, context: Context): Application { return super. new. Application(loader, Test. Base. Application: : class. java. name, context) } } class Test. Base. Application : Base. Application() { override fun application. Injector(): Android. Injector<out Dagger. Application> { return Dagger. Test. App. Component. builder(). create(this) } }
@Module Tele. Softas - Empowering innovation 2 abstract class Instrumentation. Scheduler. Module private constructor() { @Module companion object {. . . @Jvm. Static @Network. Thread @Provides fun provide. Network. Scheduler(executor: Idling. Thread. Pool. Executor): Scheduler = Schedulers. from(executor) @Jvm. Static @Provides @Dagger. Scope(Base. Application: : class) fun provide. Idling. Thread. Pool. Executor(): Idling. Thread. Pool. Executor = Idling. Thread. Pool. Executor(. . . ) } }
Tele. Softas - Empowering innovation 2 class Example. Instrumented. Test { @get: Rule var rule = Activity. Test. Rule(Main. Activity: : class. java) @Test fun example. Test() { on. View(with. Id(R. id. list. Recycler. View)). check(matches(has. Minimum. Child. Count(1))) on. View(with. Id(R. id. list. Recycler. View)). perform(View. Actions. swipe. Up()) } }
Tele. Softas - Empowering innovation 2 Alternative: Koin. io https: //insert-koin. io/
@Dagger. Scope(Base. Application: : class) Tele. Softas - Empowering innovation 2 @Component( modules = [ Android. Support. Injection. Module: : class, App. Module: : class, Activities. Module: : class, Scheduler. Module: : class, Network. Module: : class, Image. Module: : class ] ) interface App. Component : Android. Injector<Base. Application> { @Component. Builder abstract class Builder : Android. Injector. Builder<Base. Application>() }
Tele. Softas - Empowering innovation open class Base. Application 2 : Application() { override fun on. Create() { start. Koin(Koin. Application. create(). apply { android. Logger(Level. DEBUG) android. Context( this@Base. Application) modules( Plugins. Module() , App. Module(), Scheduler. Module(), Network. Module(), Image. Module(), Main. Screen. Module() ) }) } }
Tele. Softas - Empowering innovation @Module 2 abstract class App. Module private constructor() { @Binds abstract fun bind. Context(app: Base. Application): Context @Module companion object { @Jvm. Static @Provides fun provide. Resources(context: Context): Resources = context. resources } }
Tele. Softas - Empowering fun App. Module() = innovation module { 2 single { android. Context(). resources } }
Tele. Softas - Empowering innovation @dagger. Module 2 abstract class Module private constructor() { @Binds @Dagger. Scope(Main. Fragment: : class) abstract fun bind. Presenter(presenter: Main. Presenter. Impl): Main. Presenter @dagger. Module companion object { @Provides @Jvm. Static @Dagger. Scope(Main. Fragment: : class) fun provide. Service(retrofit: Retrofit) = retrofit. create<News. Service>() } }
Tele. Softas - Empoweringmodule innovation fun App. Module()= { 2 single { android. Context(). resources } } fun Module() = module { factory<Presenter> { Main. Presenter(service = get(), scheduler = get("main")) } factory< News. Service> { get<Retrofit>(). create() } }
Tele. Softas - Empowering innovation @Module 2 abstract class Network. Module private constructor() { @Module companion object { @Jvm. Static @Provides @Dagger. Scope(Base. Application: : class) fun provide. Retrofit. Client( @Network. Thread network. Scheduler: Scheduler ): Retrofit = Retrofit. Builder(). add. Call. Adapter. Factory( Rx. Java 2 Call. Adapter. Factory. create. With. Scheduler(network. Scheduler) ). base. Url(Build. Config. API_ENDPOINT). build() } }
Tele. Softas - Empowering fun App. Module() = innovation module { 2 single { android. Context(). resources } } fun Module() = module { factory<Presenter> { Main. Presenter(service = get(), scheduler = get("main")) } factory< News. Service> { get<Retrofit>(). create() } } fun Network. Module() = module { single { Retrofit = Retrofit. Builder(). add. Call. Adapter. Factory( Rx. Java 2 Call. Adapter. Factory. create. With. Scheduler(get( "network")) ). base. Url(Build. Config. API_ENDPOINT). build() } }
Tele. Softas - Empowering innovation 2 ● Singleton ● scopes based only on lifecycle, no hierarchy ● Unstable, prone to change API
Questions? Tele. Softas Savanoriu Ave. 178, LT-44150 Kaunas, Lithuania Call: +370 694 20374 Email: info@telesoftas. com www. telesoftas. com
- Slides: 33