Slide 1

Slide 1 text

SHARPER BETTER FASTER DAGGER ‡ @jrodbx @piwai

Slide 2

Slide 2 text

SHARPER BETTER FASTER DAGGER ‡

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

// compile 'com.squareup.dagger:dagger:1.2.2'
 // apt 'com.squareup.dagger:dagger-compiler:1.2.2'
 
 compile 'com.google.dagger:dagger:2.0.2'
 apt 'com.google.dagger:dagger-compiler:2.0.2'
 provided 'javax.annotation:jsr250-api:1.0'

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

@Module(
 injects = { MainActivity.class }, addsTo = AppModule.class
 )
 public final class ApiModule {
 @Provides GithubService provideGithubService(Retrofit retrofit) {
 return retrofit.create(GithubService.class);
 }
 
 @Provides Retrofit provideRetrofit(@Endpoint String url) {
 return new Retrofit.Builder()
 .baseUrl(url)
 .addConverterFactory(GsonConverterFactory.create())
 .build();
 }
 }

Slide 7

Slide 7 text

@Module(
 injects = { MainActivity.class }, addsTo = AppModule.class
 )
 public final class ApiModule {
 @Provides GithubService provideGithubService(Retrofit retrofit) {
 return retrofit.create(GithubService.class);
 }
 
 @Provides Retrofit provideRetrofit(@Endpoint String url) {
 return new Retrofit.Builder()
 .baseUrl(url)
 .addConverterFactory(GsonConverterFactory.create())
 .build();
 }
 }

Slide 8

Slide 8 text

@Module(
 injects = { MainActivity.class }, addsTo = AppModule.class
 )
 public final class ApiModule {
 @Provides GithubService provideGithubService(Retrofit retrofit) {
 return retrofit.create(GithubService.class);
 }
 
 @Provides Retrofit provideRetrofit(@Endpoint String url) {
 return new Retrofit.Builder()
 .baseUrl(url)
 .addConverterFactory(GsonConverterFactory.create())
 .build();
 }
 }

Slide 9

Slide 9 text

public class MainActivity extends Activity {
 @Inject GithubService githubService;
 
 @Override protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);
 ObjectGraph graph = getObjectGraph();
 objectGraph.inject(this);

Slide 10

Slide 10 text

public class MainActivity extends Activity {
 @Inject GithubService githubService;
 
 @Override protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);
 ObjectGraph graph = getObjectGraph();
 objectGraph.inject(this);

Slide 11

Slide 11 text

@Module(
 injects = { MainActivity.class }, addsTo = AppModule.class
 )
 public final class ApiModule {
 @Provides GithubService provideGithubService(Retrofit retrofit) {
 return retrofit.create(GithubService.class);
 }
 
 @Provides Retrofit provideRetrofit(@Endpoint String url) {
 return new Retrofit.Builder()
 .baseUrl(url)
 .addConverterFactory(GsonConverterFactory.create())
 .build();
 }
 }

Slide 12

Slide 12 text

@Module
 public final class ApiModule {
 @Provides GithubService provideGithubService(Retrofit retrofit) {
 return retrofit.create(GithubService.class);
 }
 
 @Provides Retrofit provideRetrofit(@Endpoint String url) {
 return new Retrofit.Builder()
 .baseUrl(url)
 .addConverterFactory(GsonConverterFactory.create())
 .build();
 }
 }

Slide 13

Slide 13 text

@Component(
 modules = ApiModule.class
 )
 public interface ApiComponent { Foo getFoo();
 void inject(MainActivity activity);
 }

Slide 14

Slide 14 text

@Component(
 modules = ApiModule.class
 )
 public interface ApiComponent {
 Foo getFoo();
 void inject(MainActivity activity); }

Slide 15

Slide 15 text

public class MainActivity extends Activity {
 @Inject GithubService githubService;
 
 @Override protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);
 
 ApiComponent apiComponent = DaggerApiComponent.builder().build();
 apiComponent.inject(this); …

Slide 16

Slide 16 text

public class MainActivity extends Activity {
 @Inject GithubService githubService;
 
 @Override protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);
 
 ApiComponent apiComponent = DaggerApiComponent.builder().build();
 apiComponent.inject(this); …

Slide 17

Slide 17 text

@Module class AndroidModule {…} @Module class HttpModule {…}
 @Module class ApiModule {…} …

Slide 18

Slide 18 text

@Module class AndroidModule {…} @Module class HttpModule {…}
 @Module class ApiModule {…}
 
 @Module class LoggedInModule {…} @Module class PaymentModule {…} @Module class TransactionLedgerModule {…} …

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

@Provides @Inject
 @Module

Slide 22

Slide 22 text

@Provides @Inject
 @Module @Provides2 @Inject2
 @Module2

Slide 23

Slide 23 text

ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);

Slide 24

Slide 24 text

@Module 
 public class AppModule {
 // ...
 @Provides OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 }
 // ...
 }

Slide 25

Slide 25 text

@Module 
 public class AppModule {
 // ...
 @Provides OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 }
 // ...
 } @Module2 
 public class AppModule2 {
 
 }

Slide 26

Slide 26 text

@Module 
 public class AppModule {
 // ...
 
 } @Module2 
 public class AppModule2 { @Provides2 OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides2 Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 } }

Slide 27

Slide 27 text

@Module2 
 public class AppModule2 { @Provides2 OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides2 Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 } } @Component(modules = AppModule2.class)
 public interface AppComponent {
 
 }

Slide 28

Slide 28 text

@Module2 
 public class AppModule2 { @Provides2 OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides2 Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 } } @Component(modules = AppModule2.class)
 public interface AppComponent {
 Client retrofitClient();
 OkHttpClient okHttpClient();
 }

Slide 29

Slide 29 text

@Component(modules = AppModule2.class)
 public interface AppComponent {
 AppComponentFacade dagger2Facade();
 } @Subcomponent
 public interface AppComponentFacade {
 Client retrofitClient();
 OkHttpClient okHttpClient();
 }

Slide 30

Slide 30 text

@Subcomponent
 public interface AppComponentFacade {
 Client retrofitClient();
 OkHttpClient okHttpClient();
 } @Module
 public class BridgeModule {
 private final AppComponentFacade facade;
 
 public BridgeModule(AppComponentFacade facade) {
 this.facade = facade;
 }
 
 @Provides Client retrofitClient() {
 return facade.retrofitClient();
 }
 
 @Provides OkHttpClient okHttpClient() {
 return facade.okHttpClient();
 }
 }

Slide 31

Slide 31 text

@Subcomponent
 public interface AppComponentFacade {
 Client retrofitClient();
 OkHttpClient okHttpClient();
 } @Module
 public class BridgeModule implements AppComponentFacade {
 private final AppComponentFacade facade;
 
 public BridgeModule(AppComponentFacade facade) {
 this.facade = facade;
 }
 
 @Override @Provides public Client retrofitClient() {
 return facade.retrofitClient();
 }
 
 @Override @Provides public OkHttpClient okHttpClient() {
 return facade.okHttpClient();
 }
 }

Slide 32

Slide 32 text


 ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);

Slide 33

Slide 33 text

AppComponent component = DaggerAppComponent.builder().create();
 ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);

Slide 34

Slide 34 text

AppComponent component = DaggerAppComponent.builder().create();
 AppComponentFacade facade = component.dagger2Facade();
 ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);

Slide 35

Slide 35 text

AppComponent component = DaggerAppComponent.builder().create();
 AppComponentFacade facade = component.dagger2Facade();
 BridgeModule bridge = new BridgeModule(facade);
 ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);

Slide 36

Slide 36 text

AppComponent component = DaggerAppComponent.builder().create();
 AppComponentFacade facade = component.dagger2Facade();
 BridgeModule bridge = new BridgeModule(facade);
 ObjectGraph objectGraph = ObjectGraph.create(bridge, AppModule.class);

Slide 37

Slide 37 text

@Module2 
 public class AppModule2 { @Provides2 OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides2 Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 } }

Slide 38

Slide 38 text

@Module2
 public class AppModule2 {
 @Provides2 OkHttpClient provideOkHttpClient(HostnameVerifier verifier) {
 OkHttpClient okHttpClient = new OkHttpClient();
 okHttpClient.setHostnameVerifier(verifier);
 return okHttpClient;
 }
 
 @Provides2 Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 }
 }

Slide 39

Slide 39 text

@Module
 public class AppModule {
 // ...
 }

Slide 40

Slide 40 text

@Module(injects = HostnameVerifier.class)
 public class AppModule {
 // ...
 }

Slide 41

Slide 41 text

@Module(injects = HostnameVerifier.class)
 public class AppModule {
 // ...
 } @Module2
 public class GoldenGateModule {
 private ObjectGraph objectGraph;
 
 @Provides2 public HostnameVerifier provideHostnameVerifier() {
 return objectGraph.get(HostnameVerifier.class);
 }
 
 public void setObjectGraph(ObjectGraph objectGraph) {
 this.objectGraph = objectGraph;
 }
 }

Slide 42

Slide 42 text

@Module2
 public class GoldenGateModule {
 private ObjectGraph objectGraph;
 
 @Provides2 public HostnameVerifier provideHostnameVerifier() {
 return objectGraph.get(HostnameVerifier.class);
 }
 
 public void setObjectGraph(ObjectGraph objectGraph) {
 this.objectGraph = objectGraph;
 }
 } @Module2 public class AppModule2 {
 
 // ...
 
 }

Slide 43

Slide 43 text

@Module2
 public class GoldenGateModule {
 private ObjectGraph objectGraph;
 
 @Provides2 public HostnameVerifier provideHostnameVerifier() {
 return objectGraph.get(HostnameVerifier.class);
 }
 
 public void setObjectGraph(ObjectGraph objectGraph) {
 this.objectGraph = objectGraph;
 }
 } @Module2(includes = GoldenGateModule.class)
 public class AppModule2 {
 
 // ...
 
 }

Slide 44

Slide 44 text


 AppComponent component = DaggerAppComponent.builder().create();
 
 
 AppComponentFacade facade = component.dagger2Facade();
 BridgeModule bridge = new BridgeModule(facade);
 ObjectGraph objectGraph = ObjectGraph.create(bridge, AppModule.class);


Slide 45

Slide 45 text

GoldenGateModule goldenGateModule = new GoldenGateModule();
 AppComponent component = DaggerAppComponent.builder().create();
 
 
 AppComponentFacade facade = component.dagger2Facade();
 BridgeModule bridge = new BridgeModule(facade);
 ObjectGraph objectGraph = ObjectGraph.create(bridge, AppModule.class);


Slide 46

Slide 46 text

GoldenGateModule goldenGateModule = new GoldenGateModule();
 AppComponent component = DaggerAppComponent.builder()
 .goldenGateModule(goldenGateModule)
 .create();
 AppComponentFacade facade = component.dagger2Facade();
 BridgeModule bridge = new BridgeModule(facade);
 ObjectGraph objectGraph = ObjectGraph.create(bridge, AppModule.class);


Slide 47

Slide 47 text

GoldenGateModule goldenGateModule = new GoldenGateModule();
 AppComponent component = DaggerAppComponent.builder()
 .goldenGateModule(goldenGateModule)
 .create();
 AppComponentFacade facade = component.dagger2Facade();
 BridgeModule bridge = new BridgeModule(facade);
 ObjectGraph objectGraph = ObjectGraph.create(bridge, AppModule.class);
 goldenGateModule.setObjectGraph(objectGraph);

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

Guice Dagger Dagger2 better than Spring…? improved linking + instance creation improved linking more (1x per graph)

Slide 51

Slide 51 text

@Override public ObjectGraph plus(Object... modules) {
 linkEverything();
 return makeGraph(this, plugin, modules);
 }

Slide 52

Slide 52 text

@Override public ObjectGraph plus(Object... modules) {
 linkEverything();
 return makeGraph(this, plugin, modules);
 } private Map> linkEverything() {
 … return linker.linkAll();
 } public Map> linkAll() { …
 linkRequested();
 return Collections.unmodifiableMap(bindings);
 }

Slide 53

Slide 53 text

public void linkRequested() { … while ((binding = toLink.poll()) != null) {
 if (binding instanceof DeferredBinding) { … = createBinding(…, deferred.classLoader, …);
 }
 }
 } private Binding> createBinding(…, ClassLoader classLoader, …) {
 … … = instantiate(className.concat(INJECT_ADAPTER_SUFFIX), classLoader); … } protected T instantiate(String name, ClassLoader classLoader) {
 Class> generatedClass = loadClass(classLoader, name);
 if (generatedClass == Void.class) return null;
 return (T) generatedClass.newInstance(); }

Slide 54

Slide 54 text

public void linkRequested() { … while ((binding = toLink.poll()) != null) {
 if (binding instanceof DeferredBinding) { … = createBinding(…, deferred.classLoader, …);
 }
 }
 } private Binding> createBinding(…, ClassLoader classLoader, …) {
 … … = instantiate(className.concat(INJECT_ADAPTER_SUFFIX), classLoader); … } protected T instantiate(String name, ClassLoader classLoader) {
 Class> generatedClass = loadClass(classLoader, name);
 if (generatedClass == Void.class) return null;
 return (T) generatedClass.newInstance(); }

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

@Module 
 class DripCoffeeModule {
 @Provides static Heater provideHeater(Executor executor) {
 return new CpuHeater(executor);
 }
 } [ERROR] COMPILATION ERROR : [ERROR] error: java.util.concurrent.Executor cannot be provided without an @Provides-annotated method.

Slide 57

Slide 57 text

Scoping!

Slide 58

Slide 58 text

public class TransactionHandler {
 
 private final Analytics analytics;
 private final TaxCache taxCache;
 
 private Payment paymentInFlight;
 private Order order;
 
 @Inject TransactionHandler(Analytics analytics, TaxCache taxCache) {
 this.analytics = analytics;
 this.taxCache = taxCache;
 }
 
 // ...
 }

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

public class TransactionHandler {
 
 private final Analytics analytics;
 private final TaxCache taxCache;
 
 private Payment paymentInFlight;
 private Order order;
 
 @Inject TransactionHandler(Analytics analytics, TaxCache taxCache) {
 this.analytics = analytics;
 this.taxCache = taxCache;
 }
 
 // ...
 }

Slide 61

Slide 61 text

@Singleton public class TransactionHandler {
 
 private final Analytics analytics;
 private final TaxCache taxCache;
 
 private Payment paymentInFlight;
 private Order order;
 
 @Inject TransactionHandler(Analytics analytics, TaxCache taxCache) {
 this.analytics = analytics;
 this.taxCache = taxCache;
 }
 
 // ...
 }

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

public class Linker {
 
 final Map, Binding>> bindings = new HashMap<>();
 
 Binding requestBinding(Class key) {
 return (Binding) bindings.get(key);
 }
 }

Slide 64

Slide 64 text

public class Linker {
 
 final Map, Binding>> bindings = new HashMap<>();
 
 Binding requestBinding(Class key) {
 return (Binding) bindings.get(key);
 }
 }

Slide 65

Slide 65 text

public abstract class Binding {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }

Slide 66

Slide 66 text

public abstract class Binding {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }

Slide 67

Slide 67 text

public abstract class Binding {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }

Slide 68

Slide 68 text

public abstract class Binding {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }

Slide 69

Slide 69 text

public class TransactionHandler$$InjectAdapter extends Binding {
 
 private Binding taxCache;
 private Binding analytics;
 
 public TransactionHandler$$InjectAdapter() {
 super(IS_SINGLETON);
 }
 
 @Override public void attach(Linker linker) {
 analytics = linker.requestBinding(Analytics.class);
 taxCache = linker.requestBinding(TaxCache.class);
 }
 
 @Override public TransactionHandler get() {
 return new TransactionHandler(analytics.get(), taxCache.get());
 }
 }

Slide 70

Slide 70 text

public class TransactionHandler$$InjectAdapter extends Binding {
 
 private Binding taxCache;
 private Binding analytics;
 
 public TransactionHandler$$InjectAdapter() {
 super(IS_SINGLETON);
 }
 
 @Override public void attach(Linker linker) {
 analytics = linker.requestBinding(Analytics.class);
 taxCache = linker.requestBinding(TaxCache.class);
 }
 
 @Override public TransactionHandler get() {
 return new TransactionHandler(analytics.get(), taxCache.get());
 }
 }

Slide 71

Slide 71 text

public class TransactionHandler$$InjectAdapter extends Binding {
 
 private Binding taxCache;
 private Binding analytics;
 
 public TransactionHandler$$InjectAdapter() {
 super(IS_SINGLETON);
 }
 
 @Override public void attach(Linker linker) {
 analytics = linker.requestBinding(Analytics.class);
 taxCache = linker.requestBinding(TaxCache.class);
 }
 
 @Override public TransactionHandler get() {
 return new TransactionHandler(analytics.get(), taxCache.get());
 }
 }

Slide 72

Slide 72 text

public class SingletonBinding extends Binding {
 final Binding delegate;
 
 T instance;
 
 SingletonBinding(Binding delegate) {
 this.delegate = delegate;
 }
 
 @Override void attach(Linker linker) {
 delegate.attach(linker);
 }
 
 @Override T get() {
 if (instance == null) {
 instance = delegate.get();
 }
 return instance;
 }
 }

Slide 73

Slide 73 text

public class SingletonBinding extends Binding {
 final Binding delegate;
 
 T instance;
 
 SingletonBinding(Binding delegate) {
 this.delegate = delegate;
 }
 
 @Override void attach(Linker linker) {
 delegate.attach(linker);
 }
 
 @Override T get() {
 if (instance == null) {
 instance = delegate.get();
 }
 return instance;
 }
 }

Slide 74

Slide 74 text

ObjectGraph Linker SingletonBinding Binding TransactionHandler Binding Binding

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

No content

Slide 77

Slide 77 text

ObjectGraph TransactionHandler

Slide 78

Slide 78 text

ObjectGraph TransactionHandler

Slide 79

Slide 79 text

ObjectGraph TransactionHandler PrinterHandler

Slide 80

Slide 80 text

ObjectGraph TransactionHandler PrinterHandler ObjectGraph

Slide 81

Slide 81 text

ObjectGraph TransactionHandler PrinterHandler ObjectGraph ObjectGraph AppSingleton

Slide 82

Slide 82 text

Transaction PrintScreen App

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

@Singleton public class TransactionHandler {
 
 private final Analytics analytics;
 private final TaxCache taxCache;
 
 private Payment paymentInFlight;
 private Order order;
 
 @Inject TransactionHandler(Analytics analytics, TaxCache taxCache) {
 this.analytics = analytics;
 this.taxCache = taxCache;
 }
 
 // ...
 }

Slide 85

Slide 85 text

public class TransactionFlow {
 
 private final TransactionHandler transactionHandler;
 
 @Inject TransactionFlow(TransactionHandler transactionHandler) {
 this.transactionHandler = transactionHandler;
 }
 // ...
 }

Slide 86

Slide 86 text

public class TransactionFlow {
 
 private final TransactionHandler transactionHandler;
 
 @Inject TransactionFlow(TransactionHandler transactionHandler) {
 this.transactionHandler = transactionHandler;
 }
 // ...
 } public class TransactionFlowLayout extends FrameLayout {
 
 public TransactionFlowLayout(Context context, AttributeSet attrs) {
 super(context, attrs);
 TransactionFlow transactionFlow = ???;
 // ...
 }
 }

Slide 87

Slide 87 text

@Module(injects = TransactionFlow.class)
 class TransactionModule {
 }

Slide 88

Slide 88 text

ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); @Module(injects = TransactionFlow.class)
 class TransactionModule {
 }

Slide 89

Slide 89 text

ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); @Module(injects = TransactionFlow.class)
 class TransactionModule {
 } public class TransactionFlowLayout extends FrameLayout {
 
 public TransactionFlowLayout(Context context, AttributeSet attrs) {
 super(context, attrs); ObjectGraph graph = getTransactionGraph();
 TransactionFlow transactionFlow = graph.get(TransactionFlow.class);
 // ...
 }
 }

Slide 90

Slide 90 text

public class CartPresenter {
 
 private final TransactionHandler transactionHandler;
 
 @Inject CartPresenter(TransactionHandler transactionHandler) {
 this.transactionHandler = transactionHandler;
 }
 // ...
 }

Slide 91

Slide 91 text

public class CartPresenter {
 
 private final TransactionHandler transactionHandler;
 
 @Inject CartPresenter(TransactionHandler transactionHandler) {
 this.transactionHandler = transactionHandler;
 }
 // ...
 } public class CartView extends CoordinatorLayout {
 
 public CartView(Context context, AttributeSet attrs) {
 super(context, attrs);
 ObjectGraph cartGraph = getCartGraph();
 CartPresenter cartPresenter = cartGraph.get(CartPresenter.class);
 // ...
 }
 }

Slide 92

Slide 92 text

public class CartPresenter {
 
 private final TransactionHandler transactionHandler;
 
 @Inject CartPresenter(TransactionHandler transactionHandler) {
 this.transactionHandler = transactionHandler;
 }
 // ...
 } public class CartView extends CoordinatorLayout {
 
 public CartView(Context context, AttributeSet attrs) {
 super(context, attrs);
 ObjectGraph cartGraph = getCartGraph();
 CartPresenter cartPresenter = cartGraph.get(CartPresenter.class);
 // ...
 }
 }

Slide 93

Slide 93 text

ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); 
 ObjectGraph cartGraph = transactionGraph.plus(CartScreenModule.class);

Slide 94

Slide 94 text

ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); 
 ObjectGraph cartGraph = transactionGraph.plus(CartScreenModule.class); @Module(injects = TransactionFlow.class)
 class TransactionModule {
 } @Module(injects = CartPresenter.class)
 class CartScreenModule {
 }

Slide 95

Slide 95 text

public class ObjectGraph {
 
 Linker linker;
 
 public T get(Class key) {
 Binding binding = linker.requestBinding(key);
 return binding.get();
 }
 }

Slide 96

Slide 96 text

public class ObjectGraph {
 
 Linker linker;
 ObjectGraph parentGraph;
 
 public T get(Class key) {
 if (parentGraph != null) {
 T instance = parentGraph.get(key);
 if (instance != null) {
 return instance;
 }
 }
 Binding binding = linker.requestBinding(key);
 return binding.get();
 }
 }

Slide 97

Slide 97 text

public class Linker {
 
 final Map, Binding>> bindings = new HashMap<>();
 
 Binding requestBinding(Class key) {
 return (Binding) bindings.get(key);
 }
 }

Slide 98

Slide 98 text

public class Linker {
 
 final Map, Binding>> bindings = new HashMap<>();
 
 Binding requestBinding(Class key) {
 Binding binding = (Binding) bindings.get(key);
 if (binding == null) {
 binding = loadGeneratedBinding(key);
 if (binding.singleton) {
 binding = new SingletonBinding<>(binding);
 }
 bindings.put(key, binding);
 }
 return binding;
 }
 }

Slide 99

Slide 99 text

Binding Binding CartPresenter TransactionFlow Cart screen graph Transaction graph SingletonBinding TransactionHandler

Slide 100

Slide 100 text

No content

Slide 101

Slide 101 text

Binding Binding CartPresenter TransactionFlow Cart screen graph Transaction graph SingletonBinding TransactionHandler

Slide 102

Slide 102 text

No content

Slide 103

Slide 103 text

No content

Slide 104

Slide 104 text

com.squareup.Transaction binding found in scopes marked with '*' (if any). SCOPE RegisterRootScope +-SCOPE com.squareup.dagger.LoggedIn | `-SCOPE com.squareup.ui.root.RootActivity | `-SCOPE * com.squareup.ui.root.RootFlow | `-SCOPE com.squareup.ui.seller.SellerFlow | `-SCOPE com.squareup.ui.home.HomeScreen `-SCOPE com.squareup.ui.PaymentActivity

Slide 105

Slide 105 text

@Module(injects = TransactionFlow.class)
 class TransactionModule {
 } ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class);

Slide 106

Slide 106 text

@Module(injects = TransactionFlow.class)
 class TransactionModule {
 
 @Provides @Singleton TransactionHandler transactionHandler(Analytics analytics,
 TaxCache taxCache) {
 return new TransactionHandler(analytics, taxCache);
 }
 } ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class);

Slide 107

Slide 107 text

Slide 108

Slide 108 text

@Singleton public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {}

Slide 109

Slide 109 text

@Singleton public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {}

Slide 110

Slide 110 text

@SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {}

Slide 111

Slide 111 text

@SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} 
 @Component 
 interface TransactionComponent {
 }

Slide 112

Slide 112 text

@SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component 
 interface TransactionComponent {
 }

Slide 113

Slide 113 text

@SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 }

Slide 114

Slide 114 text

@SingleInTransaction public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }

Slide 115

Slide 115 text

@SingleInTransaction public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }

Slide 116

Slide 116 text

@SingleInTransaction public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleIn { Class> value(); } @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }

Slide 117

Slide 117 text

@SingleIn(TransactionComponent.class) public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleIn { Class> value(); } @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }

Slide 118

Slide 118 text

@SingleIn(TransactionComponent.class) public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleIn { Class> value(); } @SingleIn(TransactionComponent.class)
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }

Slide 119

Slide 119 text

No content

Slide 120

Slide 120 text

Transaction flow graph Print screen graph App graph Cart screen graph

Slide 121

Slide 121 text

Transaction flow graph Print screen graph App graph Cart screen graph

Slide 122

Slide 122 text

Transaction flow graph Print screen graph App graph Cart screen graph proxy graph

Slide 123

Slide 123 text

No content

Slide 124

Slide 124 text

Transaction flow graph Print screen graph App graph Cart screen graph

Slide 125

Slide 125 text

Transaction flow graph Print screen graph App graph Cart screen graph

Slide 126

Slide 126 text

@Component
 public interface CartScreenComponent {
 CartPresenter cartPresenter();
 }

Slide 127

Slide 127 text

@Component(modules = CartScreenModule.class)
 public interface CartScreenComponent {
 CartPresenter cartPresenter();
 }

Slide 128

Slide 128 text

public interface CartScreenDependencies {
 TransactionHandler transactionHandler();
 } @Component(modules = CartScreenModule.class, dependencies = CartScreenDependencies.class)
 public interface CartScreenComponent {
 CartPresenter cartPresenter();
 }

Slide 129

Slide 129 text

No content

Slide 130

Slide 130 text

@jrodbx @piwai