Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Sword Fighting with Dagger
Mike Nakhimovich
Android Engineer NY Times
What is Dagger?
Dagger offers an alternative way to instantiate
and manage your objects through
Dependency Injection
Dagge...
Compile Time Annotation Processing (Fast)
Superpowers
Lazy
Singleton
Provider
Why Dagger?
In the Olden Days...
Old Way
public class RedditView {
private RedditPresenter presenter;
public RedditView(...) {
Gson gson = new GsonBuilder(...
Externalize Object Creation
@Provides
Gson provideGson() {
}
Create a Provider
return new GsonBuilder().create();
}
Modules
A Module is a part of your application that provides
implementations.
@Module public class DataModule {
}
@Provide...
Dependencies
@Provides methods can have their own dependencies
@Provides
RedditApi provideRedditApi(Gson gson) {
return ne...
Provides not necessary
You can also annotate constructors directly to register
public class RedditDAO {
@Inject
public Red...
Consuming Dependencies
Components
A component is a part of your application that consumes
functionality. Built from Module(s)
@Component( modules...
Register with Component
Activities/Services/Views register with an instance of a
component
public RedditView(Context conte...
Injection Fun
Now you can inject any dependencies
managed by the component.
As a field As a Constructor Param
Instantiating Dependencies Old Way
RedditPresenter presenter;
public RedditView(Context context) {
super(context);
Gson gs...
Once RedditView registers itself with a component,
Dagger will satisfy all managed dependencies with
@Inject annotations
@...
How does Dagger do it?
A static DaggerAppComponent.builder() call creates a Builder instance;
Builder creates an DaggerApp...
Generated Code
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class RedditPresenter_Factory impleme...
Dependency Chain
The Presenter has its own dependency
public class RedditPresenter {
@Inject RedditDAO dao;
}
Dependency Chain
Which has its own dependency
public class RedditDAO {
private final RedditApi api;
@Inject
public RedditD...
Dagger Eliminates “Passing Through”
Constructor Arguments
Old Way
RedditPresenter presenter;
public RedditView(...) {
super(context);
Gson gson = new GsonBuilder().create();
Reddit...
Dagger Eliminates “Passing Through”
Constructor Arguments
Dagger Way:
Inject ONLY the dependencies each
object needs
Type of Injections
Dagger has a few types of injection:
Direct
Lazy
Provider
Direct
When instance is created also create the
dependency.
public class RedditPresenter {
@Inject RedditDAO dao;
}
Lazy
Do not instantiate until .get() is called.
public class RedditPresenter {
@Inject Lazy<RedditDAO> dao;
}
Useful to ke...
Provider
Provider<T> allows you to inject multiple
instances of same object by calling .get()
public class RedditPresenter...
Singletons Old Way
public class MainActivity extends Activity {
SharedPreferences pref;
Gson gson;
ServerAPI api;
onCreate...
Singletons Dagger Way
Define objects to be Singletons
@Singleton @Provides
Gson provideGson() {
return gsonBuilder.create(...
Singletons Dagger Way
Define objects to be Singletons
@Singleton
public class RedditDAO{
@Inject
public RedditDAO() {
}
Singleton Management
@Singleton = Single instance per Component
@Singleton
@Component( modules = {DataModule.class})
publi...
Scopes
Singleton is a scope annotation
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
We can create...
Subcomponent
Creating a Subcomponent with a scope
@Subcomponent(modules = {
ActivityModule.class})
@ActivityScope
public i...
Subcomponent
plussing your component into another
component will inherit all objects
Injecting Activities
Components scoped (recreated) with each activity allows us to do silly things
like injecting an activ...
Inject a Scoped Object
@Inject
SnackbarUtil snackbarUtil;
there’s no need to pass activity into presenter and then
into th...
Scoped
If you try to inject something into an object with a
different scope, Dagger with give compilation error.
Scopes le...
Scopes cont’d
Scopes empower “activity singletons” that you
can share and not worry about reinstantiating
for each activit...
Dagger @ The New York Times
How we leveraged scope at The Times:
Inject activity intents into fragments 2 layers down
Crea...
Dagger lets us decompose our activities
Dagger @ The New York Times
We can inject something that is being provided
by a module in library project.
A/B Module with...
Dagger @ The New York Times
We can inject different implementations for
same interface spread across build variants
using ...
Sample Project
https://github.com/digitalbuddha/StoreDemo
Come work with me
http://developers.nytimes.com/careers
Upcoming SlideShare
Loading in …5
×

Sword fighting with Dagger GDG-NYC Jan 2016

857 views

Published on

Intro talk on working with Dagger.

Published in: Technology
  • Be the first to comment

Sword fighting with Dagger GDG-NYC Jan 2016

  1. 1. Sword Fighting with Dagger Mike Nakhimovich Android Engineer NY Times
  2. 2. What is Dagger? Dagger offers an alternative way to instantiate and manage your objects through Dependency Injection Dagger 2 open sourced by Google Dagger 1 – Square Guice – Google (Dagger v.0)
  3. 3. Compile Time Annotation Processing (Fast) Superpowers Lazy Singleton Provider Why Dagger?
  4. 4. In the Olden Days...
  5. 5. Old Way public class RedditView { private RedditPresenter presenter; public RedditView(...) { Gson gson = new GsonBuilder().create(); RedditApi redditApi = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson)) .build().create(RedditApi.class); RedditDAO redditDAO = new RedditDAO(redditApi); presenter=new RedditPresenter(redditDAO); }
  6. 6. Externalize Object Creation
  7. 7. @Provides Gson provideGson() { } Create a Provider return new GsonBuilder().create(); }
  8. 8. Modules A Module is a part of your application that provides implementations. @Module public class DataModule { } @Provides Gson provideGson() { return gsonBuilder.create();}
  9. 9. Dependencies @Provides methods can have their own dependencies @Provides RedditApi provideRedditApi(Gson gson) { return new Retrofit.Builder() .addConverterFactory( GsonConverterFactory.create(gson)) .build().create(RedditApi.class); }
  10. 10. Provides not necessary You can also annotate constructors directly to register public class RedditDAO { @Inject public RedditDAO(RedditApi api) { super(); } } Provided by Module
  11. 11. Consuming Dependencies
  12. 12. Components A component is a part of your application that consumes functionality. Built from Module(s) @Component( modules = {DataModule.class}) public interface AppComponent { void inject(RedditView a); }
  13. 13. Register with Component Activities/Services/Views register with an instance of a component public RedditView(Context context) { getComponent().inject(this); }
  14. 14. Injection Fun Now you can inject any dependencies managed by the component. As a field As a Constructor Param
  15. 15. Instantiating Dependencies Old Way RedditPresenter presenter; public RedditView(Context context) { super(context); Gson gson = new GsonBuilder().create(); RedditApi redditApi = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(RedditApi.class); RedditDAO redditDAO = new RedditDAO(redditApi); presenter=new RedditPresenter(redditDAO); }
  16. 16. Once RedditView registers itself with a component, Dagger will satisfy all managed dependencies with @Inject annotations @Inject RedditPresenter presenter; public RedditView(...) { getComponent().inject(this); } Instantiating Dependencies Dagger Way
  17. 17. How does Dagger do it? A static DaggerAppComponent.builder() call creates a Builder instance; Builder creates an DaggerAppComponent instance; DaggerAppComponent creates a RedditView_MembersInjector instance; RedditView_MembersInjectorr uses RedditPresenter_Factory to instantiate RedditPresenter and injects it into RedditView. Just as fast as hand written code but with fewer errors
  18. 18. Generated Code @Generated("dagger.internal.codegen.ComponentProcessor") public final class RedditPresenter_Factory implements Factory<RedditPresenter> { private final MembersInjector<RedditPresenter> membersInjector; public RedditPresenter_Factory(MembersInjector<RedditPresenter> membersInjector) { assert membersInjector != null; this.membersInjector = membersInjector; } @Override public RedditPresenter get() { RedditPresenter instance = new RedditPresenter(); membersInjector.injectMembers(instance); return instance; } public static Factory<RedditPresenter> create(MembersInjector<RedditPresenter> membersInjector) { return new RedditPresenter_Factory(membersInjector); } }
  19. 19. Dependency Chain The Presenter has its own dependency public class RedditPresenter { @Inject RedditDAO dao; }
  20. 20. Dependency Chain Which has its own dependency public class RedditDAO { private final RedditApi api; @Inject public RedditDAO(RedditApi api) { this.api = api; }
  21. 21. Dagger Eliminates “Passing Through” Constructor Arguments
  22. 22. Old Way RedditPresenter presenter; public RedditView(...) { super(context); Gson gson = new GsonBuilder().create(); RedditApi redditApi = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(RedditApi.class); RedditDAO redditDAO = new RedditDAO(redditApi); presenter=new RedditPresenter(redditDAO); }
  23. 23. Dagger Eliminates “Passing Through” Constructor Arguments Dagger Way: Inject ONLY the dependencies each object needs
  24. 24. Type of Injections Dagger has a few types of injection: Direct Lazy Provider
  25. 25. Direct When instance is created also create the dependency. public class RedditPresenter { @Inject RedditDAO dao; }
  26. 26. Lazy Do not instantiate until .get() is called. public class RedditPresenter { @Inject Lazy<RedditDAO> dao; } Useful to keep startup time down
  27. 27. Provider Provider<T> allows you to inject multiple instances of same object by calling .get() public class RedditPresenter { @Inject Provider<RedditDAO> dao; }
  28. 28. Singletons Old Way public class MainActivity extends Activity { SharedPreferences pref; Gson gson; ServerAPI api; onCreate(...) { MyApp app = (MyApp)getContext().getApplicationContext(); pref = app.getSharedPreferences(); gson = app.getGson(); api = app.getApi(); Why is MYApp managing all singletons? :-(
  29. 29. Singletons Dagger Way Define objects to be Singletons @Singleton @Provides Gson provideGson() { return gsonBuilder.create(); }
  30. 30. Singletons Dagger Way Define objects to be Singletons @Singleton public class RedditDAO{ @Inject public RedditDAO() { }
  31. 31. Singleton Management @Singleton = Single instance per Component @Singleton @Component( modules = {DataModule.class}) public interface AppComponent { void inject(RedditView a); }
  32. 32. Scopes Singleton is a scope annotation @Scope @Documented @Retention(RUNTIME) public @interface Singleton {} We can create custom scope annotations
  33. 33. Subcomponent Creating a Subcomponent with a scope @Subcomponent(modules = { ActivityModule.class}) @ActivityScope public interface ActivityComponent
  34. 34. Subcomponent plussing your component into another component will inherit all objects
  35. 35. Injecting Activities Components scoped (recreated) with each activity allows us to do silly things like injecting an activity into scoped objects: @ScopeActivity public class Toaster { @Inject Activity activity; private static void showToast() { Toast.makeText(activity, message).show(); }}
  36. 36. Inject a Scoped Object @Inject SnackbarUtil snackbarUtil; there’s no need to pass activity into presenter and then into the SnackBarMaker objects can independently satisfy their own dependencies.
  37. 37. Scoped If you try to inject something into an object with a different scope, Dagger with give compilation error. Scopes let objects “share” the same instance of anything in the scope. ToolbarPresenters, IntentHolders etc.
  38. 38. Scopes cont’d Scopes empower “activity singletons” that you can share and not worry about reinstantiating for each activity.
  39. 39. Dagger @ The New York Times How we leveraged scope at The Times: Inject activity intents into fragments 2 layers down Create a toolbar presenter, each activity and its views get access to the same presenter Inject an alerthelper/snackbar util that can show alerts.
  40. 40. Dagger lets us decompose our activities
  41. 41. Dagger @ The New York Times We can inject something that is being provided by a module in library project. A/B Module within A/B Project provides injectable A/B manager API project owns API module etc. Main Project creates a component using all the modules
  42. 42. Dagger @ The New York Times We can inject different implementations for same interface spread across build variants using a FlavorModule. Amazon Flavor provides module with Amazon Messaging Google Flavor provides module with Google Messaging
  43. 43. Sample Project https://github.com/digitalbuddha/StoreDemo
  44. 44. Come work with me http://developers.nytimes.com/careers

×