SlideShare a Scribd company logo
SHARPER BETTER FASTER DAGGER
‡
@jrodbx @piwai
SHARPER BETTER FASTER DAGGER
‡
// 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'
@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 {…}
…
@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);
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();
}
@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;

}



// ...

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

}



// ...

}
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
ObjectGraph TransactionHandler
ObjectGraph TransactionHandler
ObjectGraph TransactionHandler
PrinterHandler
ObjectGraph TransactionHandler
PrinterHandlerObjectGraph
ObjectGraph
TransactionHandlerPrinterHandler
ObjectGraph
ObjectGraph
AppSingleton
TransactionPrintScreen
App
@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
Binding
Binding
CartPresenter
TransactionFlow
Cart screen graph
Transaction graph
SingletonBinding
TransactionHandler
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();

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

}
@jrodbx @piwai

More Related Content

What's hot

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
 
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
 
Android application model
Android application modelAndroid application model
Android application modelmagicshui
 
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
 

What's hot (20)

Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
 
ChtiJUG - Introduction à Angular2
ChtiJUG - Introduction à Angular2ChtiJUG - Introduction à Angular2
ChtiJUG - Introduction à Angular2
 
Technozaure - Angular2
Technozaure - Angular2Technozaure - Angular2
Technozaure - Angular2
 
Exploring CameraX from JetPack
Exploring CameraX from JetPackExploring CameraX from JetPack
Exploring CameraX from JetPack
 
A gently introduction to AngularJS
A gently introduction to AngularJSA gently introduction to AngularJS
A gently introduction to AngularJS
 
What’s new in Android JetPack
What’s new in Android JetPackWhat’s new in Android JetPack
What’s new in Android JetPack
 
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
 
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
 
Building maintainable app #droidconzg
Building maintainable app #droidconzgBuilding maintainable app #droidconzg
Building maintainable app #droidconzg
 
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
 
Angular 8
Angular 8 Angular 8
Angular 8
 
Angular js
Angular jsAngular js
Angular js
 
Android development
Android developmentAndroid development
Android development
 
AngularJs Crash Course
AngularJs Crash CourseAngularJs Crash Course
AngularJs Crash Course
 
AngularJs presentation
AngularJs presentation AngularJs presentation
AngularJs presentation
 
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
 
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
 
Android application model
Android application modelAndroid application model
Android application model
 
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
 
AngularJS - dependency injection
AngularJS - dependency injectionAngularJS - dependency injection
AngularJS - dependency injection
 

Viewers also liked

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
 

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!
 
Défragmentez vos apps avec Mortar !
Défragmentez vos apps avec Mortar !Défragmentez vos apps avec Mortar !
Défragmentez vos apps avec Mortar !
 
Crash Fast & Furious
Crash Fast & FuriousCrash Fast & Furious
Crash Fast & Furious
 
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
 
Detect all memory leaks with LeakCanary!
 Detect all memory leaks with LeakCanary! Detect all memory leaks with LeakCanary!
Detect all memory leaks with LeakCanary!
 
Mortar & Flow - MCE 2015
Mortar & Flow - MCE 2015Mortar & Flow - MCE 2015
Mortar & Flow - MCE 2015
 

Similar to Sharper Better Faster Dagger ‡ - Droidcon SF

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
 
Dependency Injection for Android
Dependency Injection for AndroidDependency Injection for Android
Dependency Injection for Android
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 InfrastructureC.T.Co
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
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 Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
Eyal Vardi
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
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
 
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Frost
 
[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
 

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

Android architecture
Android architecture Android architecture
Android architecture
 
Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6Angular 2 Migration - JHipster Meetup 6
Angular 2 Migration - JHipster Meetup 6
 
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
 
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
 
Dependency Injection for Android
Dependency Injection for AndroidDependency Injection for Android
Dependency Injection for Android
 
Androidaop 170105090257
Androidaop 170105090257Androidaop 170105090257
Androidaop 170105090257
 
Di code steps
Di code stepsDi code steps
Di code steps
 
Migrating to Angular 2
Migrating to Angular 2Migrating to Angular 2
Migrating to Angular 2
 
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
 
Gephi Toolkit Tutorial
Gephi Toolkit TutorialGephi Toolkit Tutorial
Gephi Toolkit Tutorial
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
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
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
 
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArtArchitecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
 
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
Building an angular application -1 ( API: Golang, Database: Postgres) v1.0
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법
 
Dependency injection using dagger2
Dependency injection using dagger2Dependency injection using dagger2
Dependency injection using dagger2
 

Recently uploaded

DESIGN A COTTON SEED SEPARATION MACHINE.docx
DESIGN A COTTON SEED SEPARATION MACHINE.docxDESIGN A COTTON SEED SEPARATION MACHINE.docx
DESIGN A COTTON SEED SEPARATION MACHINE.docx
FluxPrime1
 
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdfHybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
fxintegritypublishin
 
CME397 Surface Engineering- Professional Elective
CME397 Surface Engineering- Professional ElectiveCME397 Surface Engineering- Professional Elective
CME397 Surface Engineering- Professional Elective
karthi keyan
 
Railway Signalling Principles Edition 3.pdf
Railway Signalling Principles Edition 3.pdfRailway Signalling Principles Edition 3.pdf
Railway Signalling Principles Edition 3.pdf
TeeVichai
 
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
obonagu
 
HYDROPOWER - Hydroelectric power generation
HYDROPOWER - Hydroelectric power generationHYDROPOWER - Hydroelectric power generation
HYDROPOWER - Hydroelectric power generation
Robbie Edward Sayers
 
Basic Industrial Engineering terms for apparel
Basic Industrial Engineering terms for apparelBasic Industrial Engineering terms for apparel
Basic Industrial Engineering terms for apparel
top1002
 
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
AJAYKUMARPUND1
 
6th International Conference on Machine Learning & Applications (CMLA 2024)
6th International Conference on Machine Learning & Applications (CMLA 2024)6th International Conference on Machine Learning & Applications (CMLA 2024)
6th International Conference on Machine Learning & Applications (CMLA 2024)
ClaraZara1
 
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
ssuser7dcef0
 
CW RADAR, FMCW RADAR, FMCW ALTIMETER, AND THEIR PARAMETERS
CW RADAR, FMCW RADAR, FMCW ALTIMETER, AND THEIR PARAMETERSCW RADAR, FMCW RADAR, FMCW ALTIMETER, AND THEIR PARAMETERS
CW RADAR, FMCW RADAR, FMCW ALTIMETER, AND THEIR PARAMETERS
veerababupersonal22
 
Investor-Presentation-Q1FY2024 investor presentation document.pptx
Investor-Presentation-Q1FY2024 investor presentation document.pptxInvestor-Presentation-Q1FY2024 investor presentation document.pptx
Investor-Presentation-Q1FY2024 investor presentation document.pptx
AmarGB2
 
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdf
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdfTutorial for 16S rRNA Gene Analysis with QIIME2.pdf
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdf
aqil azizi
 
weather web application report.pdf
weather web application report.pdfweather web application report.pdf
weather web application report.pdf
Pratik Pawar
 
English lab ppt no titlespecENG PPTt.pdf
English lab ppt no titlespecENG PPTt.pdfEnglish lab ppt no titlespecENG PPTt.pdf
English lab ppt no titlespecENG PPTt.pdf
BrazilAccount1
 
RAT: Retrieval Augmented Thoughts Elicit Context-Aware Reasoning in Long-Hori...
RAT: Retrieval Augmented Thoughts Elicit Context-Aware Reasoning in Long-Hori...RAT: Retrieval Augmented Thoughts Elicit Context-Aware Reasoning in Long-Hori...
RAT: Retrieval Augmented Thoughts Elicit Context-Aware Reasoning in Long-Hori...
thanhdowork
 
Building Electrical System Design & Installation
Building Electrical System Design & InstallationBuilding Electrical System Design & Installation
Building Electrical System Design & Installation
symbo111
 
Standard Reomte Control Interface - Neometrix
Standard Reomte Control Interface - NeometrixStandard Reomte Control Interface - Neometrix
Standard Reomte Control Interface - Neometrix
Neometrix_Engineering_Pvt_Ltd
 
一比一原版(SFU毕业证)西蒙菲莎大学毕业证成绩单如何办理
一比一原版(SFU毕业证)西蒙菲莎大学毕业证成绩单如何办理一比一原版(SFU毕业证)西蒙菲莎大学毕业证成绩单如何办理
一比一原版(SFU毕业证)西蒙菲莎大学毕业证成绩单如何办理
bakpo1
 
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
zwunae
 

Recently uploaded (20)

DESIGN A COTTON SEED SEPARATION MACHINE.docx
DESIGN A COTTON SEED SEPARATION MACHINE.docxDESIGN A COTTON SEED SEPARATION MACHINE.docx
DESIGN A COTTON SEED SEPARATION MACHINE.docx
 
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdfHybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
 
CME397 Surface Engineering- Professional Elective
CME397 Surface Engineering- Professional ElectiveCME397 Surface Engineering- Professional Elective
CME397 Surface Engineering- Professional Elective
 
Railway Signalling Principles Edition 3.pdf
Railway Signalling Principles Edition 3.pdfRailway Signalling Principles Edition 3.pdf
Railway Signalling Principles Edition 3.pdf
 
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
 
HYDROPOWER - Hydroelectric power generation
HYDROPOWER - Hydroelectric power generationHYDROPOWER - Hydroelectric power generation
HYDROPOWER - Hydroelectric power generation
 
Basic Industrial Engineering terms for apparel
Basic Industrial Engineering terms for apparelBasic Industrial Engineering terms for apparel
Basic Industrial Engineering terms for apparel
 
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
 
6th International Conference on Machine Learning & Applications (CMLA 2024)
6th International Conference on Machine Learning & Applications (CMLA 2024)6th International Conference on Machine Learning & Applications (CMLA 2024)
6th International Conference on Machine Learning & Applications (CMLA 2024)
 
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
NUMERICAL SIMULATIONS OF HEAT AND MASS TRANSFER IN CONDENSING HEAT EXCHANGERS...
 
CW RADAR, FMCW RADAR, FMCW ALTIMETER, AND THEIR PARAMETERS
CW RADAR, FMCW RADAR, FMCW ALTIMETER, AND THEIR PARAMETERSCW RADAR, FMCW RADAR, FMCW ALTIMETER, AND THEIR PARAMETERS
CW RADAR, FMCW RADAR, FMCW ALTIMETER, AND THEIR PARAMETERS
 
Investor-Presentation-Q1FY2024 investor presentation document.pptx
Investor-Presentation-Q1FY2024 investor presentation document.pptxInvestor-Presentation-Q1FY2024 investor presentation document.pptx
Investor-Presentation-Q1FY2024 investor presentation document.pptx
 
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdf
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdfTutorial for 16S rRNA Gene Analysis with QIIME2.pdf
Tutorial for 16S rRNA Gene Analysis with QIIME2.pdf
 
weather web application report.pdf
weather web application report.pdfweather web application report.pdf
weather web application report.pdf
 
English lab ppt no titlespecENG PPTt.pdf
English lab ppt no titlespecENG PPTt.pdfEnglish lab ppt no titlespecENG PPTt.pdf
English lab ppt no titlespecENG PPTt.pdf
 
RAT: Retrieval Augmented Thoughts Elicit Context-Aware Reasoning in Long-Hori...
RAT: Retrieval Augmented Thoughts Elicit Context-Aware Reasoning in Long-Hori...RAT: Retrieval Augmented Thoughts Elicit Context-Aware Reasoning in Long-Hori...
RAT: Retrieval Augmented Thoughts Elicit Context-Aware Reasoning in Long-Hori...
 
Building Electrical System Design & Installation
Building Electrical System Design & InstallationBuilding Electrical System Design & Installation
Building Electrical System Design & Installation
 
Standard Reomte Control Interface - Neometrix
Standard Reomte Control Interface - NeometrixStandard Reomte Control Interface - Neometrix
Standard Reomte Control Interface - Neometrix
 
一比一原版(SFU毕业证)西蒙菲莎大学毕业证成绩单如何办理
一比一原版(SFU毕业证)西蒙菲莎大学毕业证成绩单如何办理一比一原版(SFU毕业证)西蒙菲莎大学毕业证成绩单如何办理
一比一原版(SFU毕业证)西蒙菲莎大学毕业证成绩单如何办理
 
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
 

Sharper Better Faster Dagger ‡ - Droidcon SF

  • 1. SHARPER BETTER FASTER DAGGER ‡ @jrodbx @piwai
  • 3.
  • 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'
  • 5.
  • 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 {…} …
  • 19.
  • 20.
  • 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);
  • 48.
  • 49.
  • 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(); }
  • 55.
  • 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;
 }
 
 // ...
 }
  • 59.
  • 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;
 }
 
 // ...
 }
  • 62.
  • 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;
 }
 }
  • 75.
  • 76.
  • 83.
  • 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;
 }
 }
  • 100.
  • 102.
  • 103.
  • 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();
 }
  • 119.
  • 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
  • 123.
  • 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();
 }
  • 129.