SlideShare uma empresa Scribd logo
1 de 130
Baixar para ler offline
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

Mais conteúdo relacionado

Mais procurados

Android application model
Android application modelAndroid application model
Android application model
magicshui
 

Mais procurados (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
 

Destaque

Destaque (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
 

Semelhante a Sharper Better Faster Dagger ‡ - Droidcon SF

Migrating to Angular 2
Migrating to Angular 2Migrating to Angular 2
Migrating to Angular 2
FITC
 
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
 
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
 

Semelhante a 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
Dependency Injection for AndroidDependency Injection for Android
Dependency Injection for Android
 
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
 
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
 

Último

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ssuser89054b
 
Hospital management system project report.pdf
Hospital management system project report.pdfHospital management system project report.pdf
Hospital management system project report.pdf
Kamal Acharya
 
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Kandungan 087776558899
 
Standard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayStandard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power Play
Epec Engineered Technologies
 
DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakes
MayuraD1
 
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills KuwaitKuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
jaanualu31
 

Último (20)

Online food ordering system project report.pdf
Online food ordering system project report.pdfOnline food ordering system project report.pdf
Online food ordering system project report.pdf
 
Block diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptBlock diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.ppt
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
Hostel management system project report..pdf
Hostel management system project report..pdfHostel management system project report..pdf
Hostel management system project report..pdf
 
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
Unit 4_Part 1 CSE2001 Exception Handling and Function Template and Class Temp...
 
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
Bhubaneswar🌹Call Girls Bhubaneswar ❤Komal 9777949614 💟 Full Trusted CALL GIRL...
 
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptxA CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
A CASE STUDY ON CERAMIC INDUSTRY OF BANGLADESH.pptx
 
Hospital management system project report.pdf
Hospital management system project report.pdfHospital management system project report.pdf
Hospital management system project report.pdf
 
Online electricity billing project report..pdf
Online electricity billing project report..pdfOnline electricity billing project report..pdf
Online electricity billing project report..pdf
 
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
Call Girls in South Ex (delhi) call me [🔝9953056974🔝] escort service 24X7
 
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptxS1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
 
NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...
NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...
NO1 Top No1 Amil Baba In Azad Kashmir, Kashmir Black Magic Specialist Expert ...
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
COST-EFFETIVE  and Energy Efficient BUILDINGS ptxCOST-EFFETIVE  and Energy Efficient BUILDINGS ptx
COST-EFFETIVE and Energy Efficient BUILDINGS ptx
 
Standard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power PlayStandard vs Custom Battery Packs - Decoding the Power Play
Standard vs Custom Battery Packs - Decoding the Power Play
 
DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakes
 
Orlando’s Arnold Palmer Hospital Layout Strategy-1.pptx
Orlando’s Arnold Palmer Hospital Layout Strategy-1.pptxOrlando’s Arnold Palmer Hospital Layout Strategy-1.pptx
Orlando’s Arnold Palmer Hospital Layout Strategy-1.pptx
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torque
 
DC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equationDC MACHINE-Motoring and generation, Armature circuit equation
DC MACHINE-Motoring and generation, Armature circuit equation
 
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills KuwaitKuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
 

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.