SlideShare a Scribd company logo
SHARPER BETTER FASTER DAGGER
‡
@jrodbx @piwai
SHARPER BETTER FASTER DAGGER
‡
Sharper Better Faster Dagger ‡ - Droidcon SF
// 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'
Sharper Better Faster Dagger ‡ - Droidcon SF
@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();

}

}
@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();

}

}
@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();

}

}
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);
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);
@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();

}

}
@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();

}

}
@Component(

modules = ApiModule.class

)

public interface ApiComponent {
Foo getFoo();

void inject(MainActivity activity);

}
@Component(

modules = ApiModule.class

)

public interface ApiComponent {

Foo getFoo();

void inject(MainActivity activity);
}
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);
…
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);
…
@Module class AndroidModule {…}
@Module class HttpModule {…}

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

@Module class ApiModule {…}



@Module class LoggedInModule {…}
@Module class PaymentModule {…}
@Module class TransactionLedgerModule {…}
…
Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SF
@Provides
@Inject

@Module
@Provides
@Inject

@Module
@Provides2
@Inject2

@Module2
ObjectGraph objectGraph = ObjectGraph.create(AppModule.class);
@Module 

public class AppModule {

// ...

@Provides OkHttpClient provideOkHttpClient() {

return new OkHttpClient();

}



@Provides Client provideRetrofitClient(OkHttpClient client) {

return new OkClient(client);

}

// ...

}
@Module 

public class AppModule {

// ...

@Provides OkHttpClient provideOkHttpClient() {

return new OkHttpClient();

}



@Provides Client provideRetrofitClient(OkHttpClient client) {

return new OkClient(client);

}

// ...

}
@Module2 

public class AppModule2 {



}
@Module 

public class AppModule {

// ...



}
@Module2 

public class AppModule2 {
@Provides2 OkHttpClient provideOkHttpClient() {

return new OkHttpClient();

}



@Provides2 Client provideRetrofitClient(OkHttpClient client) {

return new OkClient(client);

}
}
@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 {



}
@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();

}
@Component(modules = AppModule2.class)

public interface AppComponent {

AppComponentFacade dagger2Facade();

}
@Subcomponent

public interface AppComponentFacade {

Client retrofitClient();

OkHttpClient okHttpClient();

}
@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();

}

}
@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();

}

}


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

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

AppComponentFacade facade = component.dagger2Facade();

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

AppComponentFacade facade = component.dagger2Facade();

BridgeModule bridge = new BridgeModule(facade);

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

AppComponentFacade facade = component.dagger2Facade();

BridgeModule bridge = new BridgeModule(facade);

ObjectGraph objectGraph = ObjectGraph.create(bridge, AppModule.class);
@Module2 

public class AppModule2 {
@Provides2 OkHttpClient provideOkHttpClient() {

return new OkHttpClient();

}



@Provides2 Client provideRetrofitClient(OkHttpClient client) {

return new OkClient(client);

}
}
@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);

}

}
@Module

public class AppModule {

// ...

}
@Module(injects = HostnameVerifier.class)

public class AppModule {

// ...

}
@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;

}

}
@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 {



// ...



}
@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 {



// ...



}


AppComponent component = DaggerAppComponent.builder().create();





AppComponentFacade facade = component.dagger2Facade();

BridgeModule bridge = new BridgeModule(facade);

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

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

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 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);
Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SF
Guice
Dagger
Dagger2
better than Spring…?
improved linking + instance creation
improved linking more (1x per graph)
@Override public ObjectGraph plus(Object... modules) {

linkEverything();

return makeGraph(this, plugin, modules);

}
@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);

}
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();
}
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();
}
Sharper Better Faster Dagger ‡ - Droidcon SF
@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.
Scoping!
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;

}



// ...

}
Sharper Better Faster Dagger ‡ - Droidcon SF
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;

}



// ...

}
@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;

}



// ...

}
Sharper Better Faster Dagger ‡ - Droidcon SF
public class Linker {



final Map<Class<?>, Binding<?>> bindings = new HashMap<>();



<T> Binding<T> requestBinding(Class<T> key) {

return (Binding<T>) bindings.get(key);

}

}
public class Linker {



final Map<Class<?>, Binding<?>> bindings = new HashMap<>();



<T> Binding<T> requestBinding(Class<T> key) {

return (Binding<T>) bindings.get(key);

}

}
public abstract class Binding<T> {



final boolean singleton;



protected Binding(boolean singleton) {

this.singleton = singleton;

}



abstract void attach(Linker linker);



abstract T get();

}
public abstract class Binding<T> {



final boolean singleton;



protected Binding(boolean singleton) {

this.singleton = singleton;

}



abstract void attach(Linker linker);



abstract T get();

}
public abstract class Binding<T> {



final boolean singleton;



protected Binding(boolean singleton) {

this.singleton = singleton;

}



abstract void attach(Linker linker);



abstract T get();

}
public abstract class Binding<T> {



final boolean singleton;



protected Binding(boolean singleton) {

this.singleton = singleton;

}



abstract void attach(Linker linker);



abstract T get();

}
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());

}

}
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());

}

}
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());

}

}
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;

}

}
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;

}

}
ObjectGraph Linker SingletonBinding
Binding
TransactionHandler
Binding
Binding
Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SF
ObjectGraph TransactionHandler
ObjectGraph TransactionHandler
ObjectGraph TransactionHandler
PrinterHandler
ObjectGraph TransactionHandler
PrinterHandlerObjectGraph
ObjectGraph
TransactionHandlerPrinterHandler
ObjectGraph
ObjectGraph
AppSingleton
TransactionPrintScreen
App
Sharper Better Faster Dagger ‡ - Droidcon SF
@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;

}



// ...

}
public class TransactionFlow {



private final TransactionHandler transactionHandler;



@Inject TransactionFlow(TransactionHandler transactionHandler) {

this.transactionHandler = transactionHandler;

}

// ...

}
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 = ???;

// ...

}

}
@Module(injects = TransactionFlow.class)

class TransactionModule {

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

class TransactionModule {

}
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);

// ...

}

}
public class CartPresenter {



private final TransactionHandler transactionHandler;



@Inject CartPresenter(TransactionHandler transactionHandler) {

this.transactionHandler = transactionHandler;

}

// ...

}
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);

// ...

}

}
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);

// ...

}

}
ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class);


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


ObjectGraph cartGraph = transactionGraph.plus(CartScreenModule.class);
@Module(injects = TransactionFlow.class)

class TransactionModule {

}
@Module(injects = CartPresenter.class)

class CartScreenModule {

}
public class ObjectGraph {



Linker linker;



public <T> T get(Class<T> key) {

Binding<T> binding = linker.requestBinding(key);

return binding.get();

}

}
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();

}

}
public class Linker {



final Map<Class<?>, Binding<?>> bindings = new HashMap<>();



<T> Binding<T> requestBinding(Class<T> key) {

return (Binding<T>) bindings.get(key);

}

}
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;

}

}
Binding
Binding
CartPresenter
TransactionFlow
Cart screen graph
Transaction graph
SingletonBinding
TransactionHandler
Sharper Better Faster Dagger ‡ - Droidcon SF
Binding
Binding
CartPresenter
TransactionFlow
Cart screen graph
Transaction graph
SingletonBinding
TransactionHandler
Sharper Better Faster Dagger ‡ - Droidcon SF
Sharper Better Faster Dagger ‡ - Droidcon SF
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
@Module(injects = TransactionFlow.class)

class TransactionModule {

}
ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class);
@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);
‡
@Singleton public class TransactionHandler {...}
@Module(injects = TransactionFlow.class)

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

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

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

public class TransactionModule {}
@Scope public @interface SingleInTransaction {}


@Component 

interface TransactionComponent {

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

public class TransactionModule {}
@Scope public @interface SingleInTransaction {}
@SingleInTransaction

@Component 

interface TransactionComponent {

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

public class TransactionModule {}
@Scope public @interface SingleInTransaction {}
@SingleInTransaction

@Component(modules = TransactionModule.class) 

interface TransactionComponent {

}
@SingleInTransaction public class TransactionHandler {...}
@Module

public class TransactionModule {}
@Scope public @interface SingleInTransaction {}
@SingleInTransaction

@Component(modules = TransactionModule.class) 

interface TransactionComponent {

TransactionFlow transactionFlow();

}
@SingleInTransaction public class TransactionHandler {...}
@Module

public class TransactionModule {}
@Scope public @interface SingleInTransaction {}
@SingleInTransaction

@Component(modules = TransactionModule.class) 

interface TransactionComponent {

TransactionFlow transactionFlow();

}
@SingleInTransaction public class TransactionHandler {...}
@Module

public class TransactionModule {}
@Scope public @interface SingleIn { Class<?> value(); }
@SingleInTransaction

@Component(modules = TransactionModule.class) 

interface TransactionComponent {

TransactionFlow transactionFlow();

}
@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();

}
@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();

}
Sharper Better Faster Dagger ‡ - Droidcon SF
Transaction flow graphPrint screen graph
App graph
Cart screen graph
Transaction flow graphPrint screen graph
App graph
Cart screen graph
Transaction flow graphPrint screen graph
App graph
Cart screen graph
proxy graph
Sharper Better Faster Dagger ‡ - Droidcon SF
Transaction flow graphPrint screen graph
App graph
Cart screen graph
Transaction flow graphPrint screen graph
App graph
Cart screen graph
@Component

public interface CartScreenComponent {

CartPresenter cartPresenter();

}
@Component(modules = CartScreenModule.class)

public interface CartScreenComponent {

CartPresenter cartPresenter();

}
public interface CartScreenDependencies {

TransactionHandler transactionHandler();

}
@Component(modules = CartScreenModule.class,
dependencies = CartScreenDependencies.class)

public interface CartScreenComponent {

CartPresenter cartPresenter();

}
Sharper Better Faster Dagger ‡ - Droidcon SF
@jrodbx @piwai
Ad

More Related Content

What's hot (20)

Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
Mike Nakhimovich
 
ChtiJUG - Introduction à Angular2
ChtiJUG - Introduction à Angular2ChtiJUG - Introduction à Angular2
ChtiJUG - Introduction à Angular2
Demey Emmanuel
 
Technozaure - Angular2
Technozaure - Angular2Technozaure - Angular2
Technozaure - Angular2
Demey Emmanuel
 
Exploring CameraX from JetPack
Exploring CameraX from JetPackExploring CameraX from JetPack
Exploring CameraX from JetPack
Hassan Abid
 
A gently introduction to AngularJS
A gently introduction to AngularJSA gently introduction to AngularJS
A gently introduction to AngularJS
Gregor Woiwode
 
What’s new in Android JetPack
What’s new in Android JetPackWhat’s new in Android JetPack
What’s new in Android JetPack
Hassan Abid
 
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
Fabio Collini
 
Building an app with Google's new suites
Building an app with Google's new suitesBuilding an app with Google's new suites
Building an app with Google's new suites
Toru Wonyoung Choi
 
Building maintainable app #droidconzg
Building maintainable app #droidconzgBuilding maintainable app #droidconzg
Building maintainable app #droidconzg
Kristijan Jurković
 
Jetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO ExtendedJetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO Extended
Toru Wonyoung Choi
 
Angular 8
Angular 8 Angular 8
Angular 8
Sunil OS
 
Angular js
Angular jsAngular js
Angular js
Behind D Walls
 
Android development
Android developmentAndroid development
Android development
Gregoire BARRET
 
AngularJs Crash Course
AngularJs Crash CourseAngularJs Crash Course
AngularJs Crash Course
Keith Bloomfield
 
AngularJs presentation
AngularJs presentation AngularJs presentation
AngularJs presentation
Phan Tuan
 
Dagger 2. Right way to do Dependency Injection
Dagger 2. Right way to do Dependency InjectionDagger 2. Right way to do Dependency Injection
Dagger 2. Right way to do Dependency Injection
Stfalcon Meetups
 
Dagger 2. The Right Way to Dependency Injections
Dagger 2. The Right Way to Dependency InjectionsDagger 2. The Right Way to Dependency Injections
Dagger 2. The Right Way to Dependency Injections
GlobalLogic Ukraine
 
Sword fighting with Dagger GDG-NYC Jan 2016
 Sword fighting with Dagger GDG-NYC Jan 2016 Sword fighting with Dagger GDG-NYC Jan 2016
Sword fighting with Dagger GDG-NYC Jan 2016
Mike Nakhimovich
 
AngularJS - dependency injection
AngularJS - dependency injectionAngularJS - dependency injection
AngularJS - dependency injection
Alexe Bogdan
 
Angular 2 - The Next Framework
Angular 2 - The Next FrameworkAngular 2 - The Next Framework
Angular 2 - The Next Framework
Commit University
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
Mike Nakhimovich
 
ChtiJUG - Introduction à Angular2
ChtiJUG - Introduction à Angular2ChtiJUG - Introduction à Angular2
ChtiJUG - Introduction à Angular2
Demey Emmanuel
 
Technozaure - Angular2
Technozaure - Angular2Technozaure - Angular2
Technozaure - Angular2
Demey Emmanuel
 
Exploring CameraX from JetPack
Exploring CameraX from JetPackExploring CameraX from JetPack
Exploring CameraX from JetPack
Hassan Abid
 
A gently introduction to AngularJS
A gently introduction to AngularJSA gently introduction to AngularJS
A gently introduction to AngularJS
Gregor Woiwode
 
What’s new in Android JetPack
What’s new in Android JetPackWhat’s new in Android JetPack
What’s new in Android JetPack
Hassan Abid
 
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
Fabio Collini
 
Building an app with Google's new suites
Building an app with Google's new suitesBuilding an app with Google's new suites
Building an app with Google's new suites
Toru Wonyoung Choi
 
Building maintainable app #droidconzg
Building maintainable app #droidconzgBuilding maintainable app #droidconzg
Building maintainable app #droidconzg
Kristijan Jurković
 
Jetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO ExtendedJetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO Extended
Toru Wonyoung Choi
 
Angular 8
Angular 8 Angular 8
Angular 8
Sunil OS
 
AngularJs presentation
AngularJs presentation AngularJs presentation
AngularJs presentation
Phan Tuan
 
Dagger 2. Right way to do Dependency Injection
Dagger 2. Right way to do Dependency InjectionDagger 2. Right way to do Dependency Injection
Dagger 2. Right way to do Dependency Injection
Stfalcon Meetups
 
Dagger 2. The Right Way to Dependency Injections
Dagger 2. The Right Way to Dependency InjectionsDagger 2. The Right Way to Dependency Injections
Dagger 2. The Right Way to Dependency Injections
GlobalLogic Ukraine
 
Sword fighting with Dagger GDG-NYC Jan 2016
 Sword fighting with Dagger GDG-NYC Jan 2016 Sword fighting with Dagger GDG-NYC Jan 2016
Sword fighting with Dagger GDG-NYC Jan 2016
Mike Nakhimovich
 
AngularJS - dependency injection
AngularJS - dependency injectionAngularJS - dependency injection
AngularJS - dependency injection
Alexe Bogdan
 
Angular 2 - The Next Framework
Angular 2 - The Next FrameworkAngular 2 - The Next Framework
Angular 2 - The Next Framework
Commit University
 

Viewers also liked (6)

Detect all memory leaks with LeakCanary!
 Detect all memory leaks with LeakCanary! Detect all memory leaks with LeakCanary!
Detect all memory leaks with LeakCanary!
Pierre-Yves Ricau
 
Défragmentez vos apps avec Mortar !
Défragmentez vos apps avec Mortar !Défragmentez vos apps avec Mortar !
Défragmentez vos apps avec Mortar !
Pierre-Yves Ricau
 
Crash Fast & Furious
Crash Fast & FuriousCrash Fast & Furious
Crash Fast & Furious
Pierre-Yves Ricau
 
Crash Fast - Square’s approach to Android crashes - Devoxx Be 2014
Crash Fast - Square’s approach to Android crashes - Devoxx Be 2014Crash Fast - Square’s approach to Android crashes - Devoxx Be 2014
Crash Fast - Square’s approach to Android crashes - Devoxx Be 2014
Pierre-Yves Ricau
 
Detect all memory leaks with LeakCanary!
 Detect all memory leaks with LeakCanary! Detect all memory leaks with LeakCanary!
Detect all memory leaks with LeakCanary!
Pierre-Yves Ricau
 
Mortar & Flow - MCE 2015
Mortar & Flow - MCE 2015Mortar & Flow - MCE 2015
Mortar & Flow - MCE 2015
Pierre-Yves Ricau
 
Detect all memory leaks with LeakCanary!
 Detect all memory leaks with LeakCanary! Detect all memory leaks with LeakCanary!
Detect all memory leaks with LeakCanary!
Pierre-Yves Ricau
 
Défragmentez vos apps avec Mortar !
Défragmentez vos apps avec Mortar !Défragmentez vos apps avec Mortar !
Défragmentez vos apps avec Mortar !
Pierre-Yves Ricau
 
Crash Fast - Square’s approach to Android crashes - Devoxx Be 2014
Crash Fast - Square’s approach to Android crashes - Devoxx Be 2014Crash Fast - Square’s approach to Android crashes - Devoxx Be 2014
Crash Fast - Square’s approach to Android crashes - Devoxx Be 2014
Pierre-Yves Ricau
 
Detect all memory leaks with LeakCanary!
 Detect all memory leaks with LeakCanary! Detect all memory leaks with LeakCanary!
Detect all memory leaks with LeakCanary!
Pierre-Yves Ricau
 
Ad

Similar to Sharper Better Faster Dagger ‡ - Droidcon SF (20)

Android architecture
Android architecture Android architecture
Android architecture
Trong-An Bui
 
Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6
William Marques
 
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
rhemsolutions
 
Dependency Injection for Android
Dependency Injection for AndroidDependency Injection for Android
Dependency Injection for Android
First Tuesday Bergen
 
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
First Tuesday Bergen
 
Androidaop 170105090257
Androidaop 170105090257Androidaop 170105090257
Androidaop 170105090257
newegg
 
Di code steps
Di code stepsDi code steps
Di code steps
Brian Kiptoo
 
Migrating to Angular 2
Migrating to Angular 2Migrating to Angular 2
Migrating to Angular 2
FITC
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
Bartosz Kosarzycki
 
Gephi Toolkit Tutorial
Gephi Toolkit TutorialGephi Toolkit Tutorial
Gephi Toolkit Tutorial
Gephi Consortium
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
Alexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
C.T.Co
 
Workshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native Side
Visual Engineering
 
Android workshop
Android workshopAndroid workshop
Android workshop
Michael Galpin
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
Eyal Vardi
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArtArchitecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Alina Vilk
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법
Jeado Ko
 
Dependency injection using dagger2
Dependency injection using dagger2Dependency injection using dagger2
Dependency injection using dagger2
Javad Hashemi
 
Dagger 2 - Injeção de Dependência
Dagger 2 - Injeção de DependênciaDagger 2 - Injeção de Dependência
Dagger 2 - Injeção de Dependência
Edson Menegatti
 
Android architecture
Android architecture Android architecture
Android architecture
Trong-An Bui
 
Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6
William Marques
 
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
rhemsolutions
 
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
First Tuesday Bergen
 
Androidaop 170105090257
Androidaop 170105090257Androidaop 170105090257
Androidaop 170105090257
newegg
 
Migrating to Angular 2
Migrating to Angular 2Migrating to Angular 2
Migrating to Angular 2
FITC
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
Bartosz Kosarzycki
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
Alexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
C.T.Co
 
Workshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native Side
Visual Engineering
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
Eyal Vardi
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArtArchitecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Alina Vilk
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법
Jeado Ko
 
Dependency injection using dagger2
Dependency injection using dagger2Dependency injection using dagger2
Dependency injection using dagger2
Javad Hashemi
 
Dagger 2 - Injeção de Dependência
Dagger 2 - Injeção de DependênciaDagger 2 - Injeção de Dependência
Dagger 2 - Injeção de Dependência
Edson Menegatti
 
Ad

Recently uploaded (20)

DT REPORT by Tech titan GROUP to introduce the subject design Thinking
DT REPORT by Tech titan GROUP to introduce the subject design ThinkingDT REPORT by Tech titan GROUP to introduce the subject design Thinking
DT REPORT by Tech titan GROUP to introduce the subject design Thinking
DhruvChotaliya2
 
International Journal of Distributed and Parallel systems (IJDPS)
International Journal of Distributed and Parallel systems (IJDPS)International Journal of Distributed and Parallel systems (IJDPS)
International Journal of Distributed and Parallel systems (IJDPS)
samueljackson3773
 
Compiler Design Unit1 PPT Phases of Compiler.pptx
Compiler Design Unit1 PPT Phases of Compiler.pptxCompiler Design Unit1 PPT Phases of Compiler.pptx
Compiler Design Unit1 PPT Phases of Compiler.pptx
RushaliDeshmukh2
 
RICS Membership-(The Royal Institution of Chartered Surveyors).pdf
RICS Membership-(The Royal Institution of Chartered Surveyors).pdfRICS Membership-(The Royal Institution of Chartered Surveyors).pdf
RICS Membership-(The Royal Institution of Chartered Surveyors).pdf
MohamedAbdelkader115
 
AI-assisted Software Testing (3-hours tutorial)
AI-assisted Software Testing (3-hours tutorial)AI-assisted Software Testing (3-hours tutorial)
AI-assisted Software Testing (3-hours tutorial)
Vəhid Gəruslu
 
some basics electrical and electronics knowledge
some basics electrical and electronics knowledgesome basics electrical and electronics knowledge
some basics electrical and electronics knowledge
nguyentrungdo88
 
"Boiler Feed Pump (BFP): Working, Applications, Advantages, and Limitations E...
"Boiler Feed Pump (BFP): Working, Applications, Advantages, and Limitations E..."Boiler Feed Pump (BFP): Working, Applications, Advantages, and Limitations E...
"Boiler Feed Pump (BFP): Working, Applications, Advantages, and Limitations E...
Infopitaara
 
Raish Khanji GTU 8th sem Internship Report.pdf
Raish Khanji GTU 8th sem Internship Report.pdfRaish Khanji GTU 8th sem Internship Report.pdf
Raish Khanji GTU 8th sem Internship Report.pdf
RaishKhanji
 
IntroSlides-April-BuildWithAI-VertexAI.pdf
IntroSlides-April-BuildWithAI-VertexAI.pdfIntroSlides-April-BuildWithAI-VertexAI.pdf
IntroSlides-April-BuildWithAI-VertexAI.pdf
Luiz Carneiro
 
theory-slides-for react for beginners.pptx
theory-slides-for react for beginners.pptxtheory-slides-for react for beginners.pptx
theory-slides-for react for beginners.pptx
sanchezvanessa7896
 
introduction to machine learining for beginers
introduction to machine learining for beginersintroduction to machine learining for beginers
introduction to machine learining for beginers
JoydebSheet
 
Smart_Storage_Systems_Production_Engineering.pptx
Smart_Storage_Systems_Production_Engineering.pptxSmart_Storage_Systems_Production_Engineering.pptx
Smart_Storage_Systems_Production_Engineering.pptx
rushikeshnavghare94
 
Degree_of_Automation.pdf for Instrumentation and industrial specialist
Degree_of_Automation.pdf for  Instrumentation  and industrial specialistDegree_of_Automation.pdf for  Instrumentation  and industrial specialist
Degree_of_Automation.pdf for Instrumentation and industrial specialist
shreyabhosale19
 
Mathematical foundation machine learning.pdf
Mathematical foundation machine learning.pdfMathematical foundation machine learning.pdf
Mathematical foundation machine learning.pdf
TalhaShahid49
 
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptxExplainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
MahaveerVPandit
 
Smart Storage Solutions.pptx for production engineering
Smart Storage Solutions.pptx for production engineeringSmart Storage Solutions.pptx for production engineering
Smart Storage Solutions.pptx for production engineering
rushikeshnavghare94
 
railway wheels, descaling after reheating and before forging
railway wheels, descaling after reheating and before forgingrailway wheels, descaling after reheating and before forging
railway wheels, descaling after reheating and before forging
Javad Kadkhodapour
 
Introduction to Zoomlion Earthmoving.pptx
Introduction to Zoomlion Earthmoving.pptxIntroduction to Zoomlion Earthmoving.pptx
Introduction to Zoomlion Earthmoving.pptx
AS1920
 
Development of MLR, ANN and ANFIS Models for Estimation of PCUs at Different ...
Development of MLR, ANN and ANFIS Models for Estimation of PCUs at Different ...Development of MLR, ANN and ANFIS Models for Estimation of PCUs at Different ...
Development of MLR, ANN and ANFIS Models for Estimation of PCUs at Different ...
Journal of Soft Computing in Civil Engineering
 
Introduction to FLUID MECHANICS & KINEMATICS
Introduction to FLUID MECHANICS &  KINEMATICSIntroduction to FLUID MECHANICS &  KINEMATICS
Introduction to FLUID MECHANICS & KINEMATICS
narayanaswamygdas
 
DT REPORT by Tech titan GROUP to introduce the subject design Thinking
DT REPORT by Tech titan GROUP to introduce the subject design ThinkingDT REPORT by Tech titan GROUP to introduce the subject design Thinking
DT REPORT by Tech titan GROUP to introduce the subject design Thinking
DhruvChotaliya2
 
International Journal of Distributed and Parallel systems (IJDPS)
International Journal of Distributed and Parallel systems (IJDPS)International Journal of Distributed and Parallel systems (IJDPS)
International Journal of Distributed and Parallel systems (IJDPS)
samueljackson3773
 
Compiler Design Unit1 PPT Phases of Compiler.pptx
Compiler Design Unit1 PPT Phases of Compiler.pptxCompiler Design Unit1 PPT Phases of Compiler.pptx
Compiler Design Unit1 PPT Phases of Compiler.pptx
RushaliDeshmukh2
 
RICS Membership-(The Royal Institution of Chartered Surveyors).pdf
RICS Membership-(The Royal Institution of Chartered Surveyors).pdfRICS Membership-(The Royal Institution of Chartered Surveyors).pdf
RICS Membership-(The Royal Institution of Chartered Surveyors).pdf
MohamedAbdelkader115
 
AI-assisted Software Testing (3-hours tutorial)
AI-assisted Software Testing (3-hours tutorial)AI-assisted Software Testing (3-hours tutorial)
AI-assisted Software Testing (3-hours tutorial)
Vəhid Gəruslu
 
some basics electrical and electronics knowledge
some basics electrical and electronics knowledgesome basics electrical and electronics knowledge
some basics electrical and electronics knowledge
nguyentrungdo88
 
"Boiler Feed Pump (BFP): Working, Applications, Advantages, and Limitations E...
"Boiler Feed Pump (BFP): Working, Applications, Advantages, and Limitations E..."Boiler Feed Pump (BFP): Working, Applications, Advantages, and Limitations E...
"Boiler Feed Pump (BFP): Working, Applications, Advantages, and Limitations E...
Infopitaara
 
Raish Khanji GTU 8th sem Internship Report.pdf
Raish Khanji GTU 8th sem Internship Report.pdfRaish Khanji GTU 8th sem Internship Report.pdf
Raish Khanji GTU 8th sem Internship Report.pdf
RaishKhanji
 
IntroSlides-April-BuildWithAI-VertexAI.pdf
IntroSlides-April-BuildWithAI-VertexAI.pdfIntroSlides-April-BuildWithAI-VertexAI.pdf
IntroSlides-April-BuildWithAI-VertexAI.pdf
Luiz Carneiro
 
theory-slides-for react for beginners.pptx
theory-slides-for react for beginners.pptxtheory-slides-for react for beginners.pptx
theory-slides-for react for beginners.pptx
sanchezvanessa7896
 
introduction to machine learining for beginers
introduction to machine learining for beginersintroduction to machine learining for beginers
introduction to machine learining for beginers
JoydebSheet
 
Smart_Storage_Systems_Production_Engineering.pptx
Smart_Storage_Systems_Production_Engineering.pptxSmart_Storage_Systems_Production_Engineering.pptx
Smart_Storage_Systems_Production_Engineering.pptx
rushikeshnavghare94
 
Degree_of_Automation.pdf for Instrumentation and industrial specialist
Degree_of_Automation.pdf for  Instrumentation  and industrial specialistDegree_of_Automation.pdf for  Instrumentation  and industrial specialist
Degree_of_Automation.pdf for Instrumentation and industrial specialist
shreyabhosale19
 
Mathematical foundation machine learning.pdf
Mathematical foundation machine learning.pdfMathematical foundation machine learning.pdf
Mathematical foundation machine learning.pdf
TalhaShahid49
 
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptxExplainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
Explainable-Artificial-Intelligence-XAI-A-Deep-Dive (1).pptx
MahaveerVPandit
 
Smart Storage Solutions.pptx for production engineering
Smart Storage Solutions.pptx for production engineeringSmart Storage Solutions.pptx for production engineering
Smart Storage Solutions.pptx for production engineering
rushikeshnavghare94
 
railway wheels, descaling after reheating and before forging
railway wheels, descaling after reheating and before forgingrailway wheels, descaling after reheating and before forging
railway wheels, descaling after reheating and before forging
Javad Kadkhodapour
 
Introduction to Zoomlion Earthmoving.pptx
Introduction to Zoomlion Earthmoving.pptxIntroduction to Zoomlion Earthmoving.pptx
Introduction to Zoomlion Earthmoving.pptx
AS1920
 
Introduction to FLUID MECHANICS & KINEMATICS
Introduction to FLUID MECHANICS &  KINEMATICSIntroduction to FLUID MECHANICS &  KINEMATICS
Introduction to FLUID MECHANICS & KINEMATICS
narayanaswamygdas
 

Sharper Better Faster Dagger ‡ - Droidcon SF

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

  • 45. 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);

  • 46. 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);

  • 47. 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);
  • 50. Guice Dagger Dagger2 better than Spring…? improved linking + instance creation improved linking more (1x per graph)
  • 51. @Override public ObjectGraph plus(Object... modules) {
 linkEverything();
 return makeGraph(this, plugin, modules);
 }
  • 52. @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);
 }
  • 53. 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(); }
  • 54. 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(); }
  • 56. @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.
  • 58. 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;
 }
 
 // ...
 }
  • 60. 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;
 }
 
 // ...
 }
  • 61. @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;
 }
 
 // ...
 }
  • 63. public class Linker {
 
 final Map<Class<?>, Binding<?>> bindings = new HashMap<>();
 
 <T> Binding<T> requestBinding(Class<T> key) {
 return (Binding<T>) bindings.get(key);
 }
 }
  • 64. public class Linker {
 
 final Map<Class<?>, Binding<?>> bindings = new HashMap<>();
 
 <T> Binding<T> requestBinding(Class<T> key) {
 return (Binding<T>) bindings.get(key);
 }
 }
  • 65. public abstract class Binding<T> {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }
  • 66. public abstract class Binding<T> {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }
  • 67. public abstract class Binding<T> {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }
  • 68. public abstract class Binding<T> {
 
 final boolean singleton;
 
 protected Binding(boolean singleton) {
 this.singleton = singleton;
 }
 
 abstract void attach(Linker linker);
 
 abstract T get();
 }
  • 69. 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());
 }
 }
  • 70. 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());
 }
 }
  • 71. 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());
 }
 }
  • 72. 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;
 }
 }
  • 73. 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;
 }
 }
  • 84. @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;
 }
 
 // ...
 }
  • 85. public class TransactionFlow {
 
 private final TransactionHandler transactionHandler;
 
 @Inject TransactionFlow(TransactionHandler transactionHandler) {
 this.transactionHandler = transactionHandler;
 }
 // ...
 }
  • 86. 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 = ???;
 // ...
 }
 }
  • 88. ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); @Module(injects = TransactionFlow.class)
 class TransactionModule {
 }
  • 89. 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);
 // ...
 }
 }
  • 90. public class CartPresenter {
 
 private final TransactionHandler transactionHandler;
 
 @Inject CartPresenter(TransactionHandler transactionHandler) {
 this.transactionHandler = transactionHandler;
 }
 // ...
 }
  • 91. 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);
 // ...
 }
 }
  • 92. 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);
 // ...
 }
 }
  • 93. ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); 
 ObjectGraph cartGraph = transactionGraph.plus(CartScreenModule.class);
  • 94. ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class); 
 ObjectGraph cartGraph = transactionGraph.plus(CartScreenModule.class); @Module(injects = TransactionFlow.class)
 class TransactionModule {
 } @Module(injects = CartPresenter.class)
 class CartScreenModule {
 }
  • 95. public class ObjectGraph {
 
 Linker linker;
 
 public <T> T get(Class<T> key) {
 Binding<T> binding = linker.requestBinding(key);
 return binding.get();
 }
 }
  • 96. 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();
 }
 }
  • 97. public class Linker {
 
 final Map<Class<?>, Binding<?>> bindings = new HashMap<>();
 
 <T> Binding<T> requestBinding(Class<T> key) {
 return (Binding<T>) bindings.get(key);
 }
 }
  • 98. 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;
 }
 }
  • 104. 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
  • 105. @Module(injects = TransactionFlow.class)
 class TransactionModule {
 } ObjectGraph transactionGraph = appGraph.plus(TransactionModule.class);
  • 106. @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);
  • 107.
  • 108. @Singleton public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {}
  • 109. @Singleton public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {}
  • 110. @SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {}
  • 111. @SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} 
 @Component 
 interface TransactionComponent {
 }
  • 112. @SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component 
 interface TransactionComponent {
 }
  • 113. @SingleInTransaction public class TransactionHandler {...} @Module(injects = TransactionFlow.class)
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 }
  • 114. @SingleInTransaction public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }
  • 115. @SingleInTransaction public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleInTransaction {} @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }
  • 116. @SingleInTransaction public class TransactionHandler {...} @Module
 public class TransactionModule {} @Scope public @interface SingleIn { Class<?> value(); } @SingleInTransaction
 @Component(modules = TransactionModule.class) 
 interface TransactionComponent {
 TransactionFlow transactionFlow();
 }
  • 117. @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();
 }
  • 118. @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();
 }
  • 120. Transaction flow graphPrint screen graph App graph Cart screen graph
  • 121. Transaction flow graphPrint screen graph App graph Cart screen graph
  • 122. Transaction flow graphPrint screen graph App graph Cart screen graph proxy graph
  • 124. Transaction flow graphPrint screen graph App graph Cart screen graph
  • 125. Transaction flow graphPrint screen graph App graph Cart screen graph
  • 126. @Component
 public interface CartScreenComponent {
 CartPresenter cartPresenter();
 }
  • 127. @Component(modules = CartScreenModule.class)
 public interface CartScreenComponent {
 CartPresenter cartPresenter();
 }
  • 128. public interface CartScreenDependencies {
 TransactionHandler transactionHandler();
 } @Component(modules = CartScreenModule.class, dependencies = CartScreenDependencies.class)
 public interface CartScreenComponent {
 CartPresenter cartPresenter();
 }