Slide 1

Slide 1 text

uber/motif @shaunkawano

Slide 2

Slide 2 text

•DI library - simple API optimized for nested scopes •Generates Dagger code for actual DI •Under heavily development uber/motif

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Usage

Slide 5

Slide 5 text

@motif.Scope interface AppScope { @motif.Objects abstract class Objects { fun okHttpClient(): OkHttpClient = 
 OkHttpClient.Builder().build() fun retrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl("") .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync()) .build() fun service(retrofit: Retrofit): Service = retrofit.create(Service::class.java) fun api(service: Service): Api = ApiClient(service) } }

Slide 6

Slide 6 text

@motif.Scope interface AppScope { @motif.Objects abstract class Objects { fun okHttpClient(): OkHttpClient = 
 OkHttpClient.Builder().build() fun retrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl("") .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync()) .build() fun service(retrofit: Retrofit): Service = retrofit.create(Service::class.java) fun api(service: Service): Api = ApiClient(service) } }

Slide 7

Slide 7 text

@motif.Scope interface AppScope { @motif.Objects abstract class Objects { fun okHttpClient(): OkHttpClient = 
 OkHttpClient.Builder().build() fun retrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl("") .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync()) .build() fun service(retrofit: Retrofit): Service = retrofit.create(Service::class.java) fun api(service: Service): Api = ApiClient(service) } }

Slide 8

Slide 8 text

@motif.Scope interface AppScope { @motif.Objects abstract class Objects { fun okHttpClient(): OkHttpClient = 
 OkHttpClient.Builder().build() fun retrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl("") .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync()) .build() fun service(retrofit: Retrofit): Service = retrofit.create(Service::class.java) fun api(service: Service): Api = ApiClient(service) } }

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

public class AppScopeImpl implements AppScope { private final Component component; public AppScopeImpl(Dependencies dependencies) { this.component = DaggerAppScopeImpl_Component.builder() .dependencies(dependencies) .module(new Module()) .build(); } public AppScopeImpl() { this(new Dependencies() {}); } public interface Dependencies { } @DaggerScope @dagger.Component( dependencies = Dependencies.class, modules = Module.class ) interface Component { } private static class Objects extends AppScope.Objects { } …

Slide 12

Slide 12 text

@dagger.Module class Module { private final AppScope.Objects objects = new Objects(); @Provides AppScope appScope() { return AppScopeImpl.this; } @Provides @DaggerScope OkHttpClient okHttpClient() { return objects.okHttpClient(); } @Provides @DaggerScope Retrofit retrofit(OkHttpClient okHttpClient) { return objects.retrofit(okHttpClient); } @Provides @DaggerScope Service service(Retrofit retrofit) { return objects.service(retrofit); } … }

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

public final class AppScopeImpl_Module_ApiFactory implements Factory { private final AppScopeImpl.Module module; private final Provider serviceProvider; public AppScopeImpl_Module_ApiFactory( AppScopeImpl.Module module, Provider serviceProvider) { this.module = module; this.serviceProvider = serviceProvider; } @Override public Api get() { return provideInstance(module, serviceProvider); } public static Api provideInstance(AppScopeImpl.Module module, Provider serviceProvider) { return proxyApi(module, serviceProvider.get()); } … public static Api proxyApi(AppScopeImpl.Module instance, Service service) { return Preconditions.checkNotNull( instance.api(service), "Cannot return null from a non-@Nullable @Provides method"); } }

Slide 15

Slide 15 text

It generates code similar to or the same as what dagger generates

Slide 16

Slide 16 text

dagger & motif?

Slide 17

Slide 17 text

# of concepts

Slide 18

Slide 18 text

@RootComponent.Scope @Component(modules = RootComponent.Module.class) public interface RootComponent { RootController controller(); LoggedInComponent.Builder loggedIn(); @dagger.Component.Builder interface Builder { @BindsInstance Builder viewGroup(@Root ViewGroup parent); RootComponent build(); } @dagger.Module abstract class Module { @Scope @Provides static RootView view(@Root ViewGroup parent) { return RootView.create(parent); } } @javax.inject.Scope @interface Scope {} @Qualifier @interface Root {} }

Slide 19

Slide 19 text

@RootComponent.Scope @Component(modules = RootComponent.Module.class) public interface RootComponent { RootController controller(); LoggedInComponent.Builder loggedIn(); @dagger.Component.Builder interface Builder { @BindsInstance Builder viewGroup(@Root ViewGroup parent); RootComponent build(); } @dagger.Module abstract class Module { @Scope @Provides static RootView view(@Root ViewGroup parent) { return RootView.create(parent); } } @javax.inject.Scope @interface Scope {} @Qualifier @interface Root {} } •@Scope •@Component / @Subcomponent •@Component.Buidler / @Subcomponent.Builder •@Qualifier •@BindsInstance •@Module •@Provides •abstract @Modules •static @Provides •Component provision method •Component factory method •Constructor injection

Slide 20

Slide 20 text

@Scope public interface RootScope { RootController controller(); LoggedInScope loggedIn(ViewGroup parentViewGroup); @motif.Objects abstract class Objects { abstract RootController controller(); RootView view(ViewGroup viewGroup) { return RootView.create(viewGroup); } } }

Slide 21

Slide 21 text

@Scope public interface RootScope { RootController controller(); LoggedInScope loggedIn(ViewGroup parentViewGroup); @motif.Objects abstract class Objects { abstract RootController controller(); RootView view(ViewGroup viewGroup) { return RootView.create(viewGroup); } } } •@motif.Scope •@motif.Objects •Access method •Child method •Factory method (Basic) •Factory method (Constructor Injected)

Slide 22

Slide 22 text

•dagger •Fully customizable •Required to understand its concepts •Code readability concern •motif •Less customizable •Less concepts •More readable Philosophy

Slide 23

Slide 23 text

@Expose

Slide 24

Slide 24 text

@motif.Scope interface ChildScope { @motif.Objects open class Objects { fun childService(retrofit: Retrofit): ChildService = retrofit.create(ChildService::class.java) fun childApi(childService: ChildService): ChildApi = ChildApiClient(childService) } }

Slide 25

Slide 25 text

@motif.Scope interface ChildScope { @motif.Objects open class Objects { fun childService(retrofit: Retrofit): ChildService = retrofit.create(ChildService::class.java) fun childApi(childService: ChildService): ChildApi = ChildApiClient(childService) } }

Slide 26

Slide 26 text

@motif.Scope interface AppScope { fun childScope(): ChildScope @motif.Objects open class Objects { fun okHttpClient(): OkHttpClient = OkHttpClient.Builder().build() fun retrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl(“") .addCallAdapterFactory(RxJava2CallAdapterFactory .createAsync()).build() fun service(retrofit: Retrofit): Service = retrofit.create(Service::class.java) fun api(service: Service): Api = ApiClient(service) } }

Slide 27

Slide 27 text

@motif.Scope interface AppScope { fun childScope(): ChildScope @motif.Objects open class Objects { fun okHttpClient(): OkHttpClient = OkHttpClient.Builder().build() fun retrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl(“") .addCallAdapterFactory(RxJava2CallAdapterFactory .createAsync()).build() fun service(retrofit: Retrofit): Service = retrofit.create(Service::class.java) fun api(service: Service): Api = ApiClient(service) } }

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

@Expose

Slide 30

Slide 30 text

@motif.Scope interface AppScope { fun childScope(): ChildScope @motif.Objects open class Objects { fun okHttpClient(): OkHttpClient = OkHttpClient.Builder().build() fun retrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl(“") .addCallAdapterFactory(RxJava2CallAdapterFactory .createAsync()) .build() fun service(retrofit: Retrofit): Service = retrofit.create(Service::class.java) fun api(service: Service): Api = ApiClient(service) } }

Slide 31

Slide 31 text

@motif.Scope interface AppScope { fun childScope(): ChildScope @motif.Objects open class Objects { fun okHttpClient(): OkHttpClient = OkHttpClient.Builder().build() @Expose fun retrofit(okHttpClient: OkHttpClient): Retrofit = Retrofit.Builder().client(okHttpClient).baseUrl("") .addCallAdapterFactory(RxJava2CallAdapterFactory .createAsync()) .build() fun service(retrofit: Retrofit): Service = retrofit.create(Service::class.java) fun api(service: Service): Api = ApiClient(service) } }

Slide 32

Slide 32 text

Summary

Slide 33

Slide 33 text

•DI library •Clearly different from Dagger •Under heavily development •Read and understand its philosophy before choosing to use it or not uber/motif

Slide 34

Slide 34 text

Uber/Motif @shaunkawano Thank you!