Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Sharper Better Faster Dagger ‡ - Droidcon SF

7 452 vues

Publié le

Slides for our (John Rodriguez and myself) talk at Droidcon SF: http://sf.droidcon.com/schedule

For the past 3 years, Square Register Android has leveraged Dagger † to wire up Java objects. However, the app scope hierarchy and complexity increased and we started having bugs and crashes related to scoping errors. This talk will show how to structure an app around Dagger2 ‡ and present a strategy for incrementally migrating from Dagger1 to Dagger2.

Publié dans : Ingénierie
  • Soyez le premier à commenter

Sharper Better Faster Dagger ‡ - Droidcon SF

  1. 1. SHARPER BETTER FASTER DAGGER ‡ @jrodbx @piwai
  2. 2. SHARPER BETTER FASTER DAGGER ‡
  3. 3. // 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'
  4. 4. @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();
 }
 }
  5. 5. @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();
 }
 }
  6. 6. @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();
 }
 }
  7. 7. 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);
  8. 8. 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);
  9. 9. @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();
 }
 }
  10. 10. @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();
 }
 }
  11. 11. @Component(
 modules = ApiModule.class
 )
 public interface ApiComponent { Foo getFoo();
 void inject(MainActivity activity);
 }
  12. 12. @Component(
 modules = ApiModule.class
 )
 public interface ApiComponent {
 Foo getFoo();
 void inject(MainActivity activity); }
  13. 13. 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); …
  14. 14. 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); …
  15. 15. @Module class AndroidModule {…} @Module class HttpModule {…}
 @Module class ApiModule {…} …
  16. 16. @Module class AndroidModule {…} @Module class HttpModule {…}
 @Module class ApiModule {…}
 
 @Module class LoggedInModule {…} @Module class PaymentModule {…} @Module class TransactionLedgerModule {…} …
  17. 17. @Provides @Inject
 @Module
  18. 18. @Provides @Inject
 @Module @Provides2 @Inject2
 @Module2
  19. 19. ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);
  20. 20. @Module 
 public class AppModule {
 // ...
 @Provides OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 }
 // ...
 }
  21. 21. @Module 
 public class AppModule {
 // ...
 @Provides OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 }
 // ...
 } @Module2 
 public class AppModule2 {
 
 }
  22. 22. @Module 
 public class AppModule {
 // ...
 
 } @Module2 
 public class AppModule2 { @Provides2 OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides2 Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 } }
  23. 23. @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 {
 
 }
  24. 24. @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();
 }
  25. 25. @Component(modules = AppModule2.class)
 public interface AppComponent {
 AppComponentFacade dagger2Facade();
 } @Subcomponent
 public interface AppComponentFacade {
 Client retrofitClient();
 OkHttpClient okHttpClient();
 }
  26. 26. @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();
 }
 }
  27. 27. @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();
 }
 }
  28. 28. 
 ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);
  29. 29. AppComponent component = DaggerAppComponent.builder().create();
 ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);
  30. 30. AppComponent component = DaggerAppComponent.builder().create();
 AppComponentFacade facade = component.dagger2Facade();
 ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);
  31. 31. AppComponent component = DaggerAppComponent.builder().create();
 AppComponentFacade facade = component.dagger2Facade();
 BridgeModule bridge = new BridgeModule(facade);
 ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);
  32. 32. AppComponent component = DaggerAppComponent.builder().create();
 AppComponentFacade facade = component.dagger2Facade();
 BridgeModule bridge = new BridgeModule(facade);
 ObjectGraph objectGraph = ObjectGraph.create(bridge, AppModule.class);
  33. 33. @Module2 
 public class AppModule2 { @Provides2 OkHttpClient provideOkHttpClient() {
 return new OkHttpClient();
 }
 
 @Provides2 Client provideRetrofitClient(OkHttpClient client) {
 return new OkClient(client);
 } }
  34. 34. @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);
 }
 }
  35. 35. @Module
 public class AppModule {
 // ...
 }
  36. 36. @Module(injects = HostnameVerifier.class)
 public class AppModule {
 // ...
 }
  37. 37. @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;
 }
 }
  38. 38. @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 {
 
 // ...
 
 }
  39. 39. @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 {
 
 // ...
 
 }
  40. 40. 
 AppComponent component = DaggerAppComponent.builder().create();
 
 
 AppComponentFacade facade = component.dagger2Facade();
 BridgeModule bridge = new BridgeModule(facade);
 ObjectGraph objectGraph = ObjectGraph.create(bridge, AppModule.class);

  41. 41. 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);

  42. 42. 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);

  43. 43. 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);
  44. 44. Guice Dagger Dagger2 better than Spring…? improved linking + instance creation improved linking more (1x per graph)
  45. 45. @Override public ObjectGraph plus(Object... modules) {
 linkEverything();
 return makeGraph(this, plugin, modules);
 }
  46. 46. @Override public ObjectGraph plus(Object... modules) {
 linkEverything();
 return makeGraph(this, plugin, modules);
 } private Map<String, Binding<?>> linkEverything() {
 … return linker.linkAll();
 } public Map<String, Binding<?>> linkAll() { …
 linkRequested();
 return Collections.unmodifiableMap(bindings);
 }
  47. 47. 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> T instantiate(String name, ClassLoader classLoader) {
 Class<?> generatedClass = loadClass(classLoader, name);
 if (generatedClass == Void.class) return null;
 return (T) generatedClass.newInstance(); }
  48. 48. 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> T instantiate(String name, ClassLoader classLoader) {
 Class<?> generatedClass = loadClass(classLoader, name);
 if (generatedClass == Void.class) return null;
 return (T) generatedClass.newInstance(); }
  49. 49. @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.
  50. 50. Scoping!
  51. 51. 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;
 }
 
 // ...
 }
  52. 52. 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;
 }
 
 // ...
 }
  53. 53. @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;
 }
 
 // ...
 }
  54. 54. public class Linker {
 
 final Map<Class<?>, Binding<?>> bindings = new HashMap<>();
 
 <T> Binding<T> requestBinding(Class<T> key) {
 return (Binding<T>) bindings.get(key);
 }
 }
  55. 55. public class Linker {
 
 final Map<Class<?>, Binding<?>> bindings = new HashMap<>();
 
 <T> Binding<T> requestBinding(Class<T> key) {
 return (Binding<T>) bindings.get(key);
 }
 }
  56. 56. public abstract class Binding<T> {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }
  57. 57. public abstract class Binding<T> {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }
  58. 58. public abstract class Binding<T> {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }
  59. 59. public abstract class Binding<T> {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }
  60. 60. public class TransactionHandler$$InjectAdapter extends Binding<TransactionHandler> {
 
 private Binding<TaxCache> taxCache;
 private Binding<Analytics> 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());
 }
 }
  61. 61. public class TransactionHandler$$InjectAdapter extends Binding<TransactionHandler> {
 
 private Binding<TaxCache> taxCache;
 private Binding<Analytics> 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());
 }
 }
  62. 62. public class TransactionHandler$$InjectAdapter extends Binding<TransactionHandler> {
 
 private Binding<TaxCache> taxCache;
 private Binding<Analytics> 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());
 }
 }
  63. 63. public class SingletonBinding<T> extends Binding<T> {
 final Binding<T> delegate;
 
 T instance;
 
 SingletonBinding(Binding<T> delegate) {
 this.delegate = delegate;
 }
 
 @Override void attach(Linker linker) {
 delegate.attach(linker);
 }
 
 @Override T get() {
 if (instance == null) {
 instance = delegate.get();
 }
 return instance;
 }
 }
  64. 64. public class SingletonBinding<T> extends Binding<T> {
 final Binding<T> delegate;
 
 T instance;
 
 SingletonBinding(Binding<T> delegate) {
 this.delegate = delegate;
 }
 
 @Override void attach(Linker linker) {
 delegate.attach(linker);
 }
 
 @Override T get() {
 if (instance == null) {
 instance = delegate.get();
 }
 return instance;
 }
 }
  65. 65. ObjectGraph Linker SingletonBinding Binding TransactionHandler Binding Binding
  66. 66. ObjectGraph TransactionHandler
  67. 67. ObjectGraph TransactionHandler
  68. 68. ObjectGraph TransactionHandler PrinterHandler
  69. 69. ObjectGraph TransactionHandler PrinterHandlerObjectGraph
  70. 70. ObjectGraph TransactionHandlerPrinterHandler ObjectGraph ObjectGraph AppSingleton
  71. 71. TransactionPrintScreen App
  72. 72. @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;
 }
 
 // ...
 }
  73. 73. public class TransactionFlow {
 
 private final TransactionHandler transactionHandler;
 
 @Inject TransactionFlow(TransactionHandler transactionHandler) {
 this.transactionHandler = transactionHandler;
 }
 // ...
 }
  74. 74. 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 = ???;
 // ...
 }
 }
  75. 75. @Module(injects = TransactionFlow.class)
 class TransactionModule {
 }
  76. 76. ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); @Module(injects = TransactionFlow.class)
 class TransactionModule {
 }
  77. 77. 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);
 // ...
 }
 }
  78. 78. public class CartPresenter {
 
 private final TransactionHandler transactionHandler;
 
 @Inject CartPresenter(TransactionHandler transactionHandler) {
 this.transactionHandler = transactionHandler;
 }
 // ...
 }
  79. 79. 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);
 // ...
 }
 }
  80. 80. 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);
 // ...
 }
 }
  81. 81. ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); 
 ObjectGraph cartGraph = transactionGraph.plus(CartScreenModule.class);
  82. 82. ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); 
 ObjectGraph cartGraph = transactionGraph.plus(CartScreenModule.class); @Module(injects = TransactionFlow.class)
 class TransactionModule {
 } @Module(injects = CartPresenter.class)
 class CartScreenModule {
 }
  83. 83. public class ObjectGraph {
 
 Linker linker;
 
 public <T> T get(Class<T> key) {
 Binding<T> binding = linker.requestBinding(key);
 return binding.get();
 }
 }
  84. 84. public class ObjectGraph {
 
 Linker linker;
 ObjectGraph parentGraph;
 
 public <T> T get(Class<T> key) {
 if (parentGraph != null) {
 T instance = parentGraph.get(key);
 if (instance != null) {
 return instance;
 }
 }
 Binding<T> binding = linker.requestBinding(key);
 return binding.get();
 }
 }
  85. 85. public class Linker {
 
 final Map<Class<?>, Binding<?>> bindings = new HashMap<>();
 
 <T> Binding<T> requestBinding(Class<T> key) {
 return (Binding<T>) bindings.get(key);
 }
 }
  86. 86. public class Linker {
 
 final Map<Class<?>, Binding<?>> bindings = new HashMap<>();
 
 <T> Binding<T> requestBinding(Class<T> key) {
 Binding<T> binding = (Binding<T>) bindings.get(key);
 if (binding == null) {
 binding = loadGeneratedBinding(key);
 if (binding.singleton) {
 binding = new SingletonBinding<>(binding);
 }
 bindings.put(key, binding);
 }
 return binding;
 }
 }
  87. 87. Binding Binding CartPresenter TransactionFlow Cart screen graph Transaction graph SingletonBinding TransactionHandler
  88. 88. Binding Binding CartPresenter TransactionFlow Cart screen graph Transaction graph SingletonBinding TransactionHandler
  89. 89. 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
  90. 90. @Module(injects = TransactionFlow.class)
 class TransactionModule {
 } ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class);
  91. 91. @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);
  92. 92.
  93. 93. @Singleton public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {}
  94. 94. @Singleton public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {}
  95. 95. @SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {}
  96. 96. @SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} 
 @Component 
 interface TransactionComponent {
 }
  97. 97. @SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component 
 interface TransactionComponent {
 }
  98. 98. @SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 }
  99. 99. @SingleInTransaction public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }
  100. 100. @SingleInTransaction public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }
  101. 101. @SingleInTransaction public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleIn { Class<?> value(); } @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }
  102. 102. @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();
 }
  103. 103. @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();
 }
  104. 104. Transaction flow graphPrint screen graph App graph Cart screen graph
  105. 105. Transaction flow graphPrint screen graph App graph Cart screen graph
  106. 106. Transaction flow graphPrint screen graph App graph Cart screen graph proxy graph
  107. 107. Transaction flow graphPrint screen graph App graph Cart screen graph
  108. 108. Transaction flow graphPrint screen graph App graph Cart screen graph
  109. 109. @Component
 public interface CartScreenComponent {
 CartPresenter cartPresenter();
 }
  110. 110. @Component(modules = CartScreenModule.class)
 public interface CartScreenComponent {
 CartPresenter cartPresenter();
 }
  111. 111. public interface CartScreenDependencies {
 TransactionHandler transactionHandler();
 } @Component(modules = CartScreenModule.class, dependencies = CartScreenDependencies.class)
 public interface CartScreenComponent {
 CartPresenter cartPresenter();
 }
  112. 112. @jrodbx @piwai

×