František Gažo
Android developer at
"Dependency injection is a software design pattern in which one or more dependencies are injected, or passed by reference, into a dependent object. This pattern separates the creation of object's dependencies from its own behaviour, which allows program designs to be loosely coupled and to follow the Inversion of Control and Single Responsibility principle."
reduce coupling
more flexible
easier to test
DIY
Library
No longer supported since August 2016
Deprecated since September 2016
DI framework for both Java and Android
fully static, compile-time
version 1 created by Square
maintained by Google
dependencies {
compile 'com.google.dagger:dagger:2.x'
annotationProcessor 'com.google.dagger:dagger-compiler:2.x'
}
Target
Component
Module
MainActivity
AppComponent
AppModule
@Inject
@Component
@Module
@Provides
@Qualifier
@Retention(RUNTIME)
public @interface UserName {
}
class UserInfoActivity extends Activity {
@Inject
@UserName
String mUserName;
}
class UserInfoActivity extends Activity {
@Inject
@Named("user-name")
String mUserName;
}
@Module
class UserModule {
@Provides
@Named("user-name")
String provideUserName() {...}
}
Dagger generates Component implementations
manage them yourself
@Scope
@Retention(RUNTIME)
public @interface UserScope {
}
@Singleton
@Component(modules = {
DataModule.class
})
interface AppComponent { ... }
@Module
class DataModule {
@Provides
@Singleton
DB provideDatabase() {...}
}
bind Component to the Scope
Module cannot provide in different Scopes
@UserScope
@Subcomponent(modules = {
UserModule.class
})
interface UserComponent { ... }
@Module
class UserModule {
//...
@Provides
@UserScope
USer provideUser() {...}
}
@Subcomponent
@Component
@?
// parent
@Component(modules = ParentModule.class)
interface ParentComponent {
ChildComponent childComponent();
// ChildComponent childComponent(ChildModule m);
}
@Module
class ParentModule { ... }
// child
@Subcomponent(modules = ChildModule.class)
interface ChildComponent { ... }
@Module
class ChildModule { ... }
ParentComponent parent = DaggerParentComponent.create();
ChildComponent child = parent.childComponent();
//ChildComponent child = parent.childComponent(new ChildModule(...));
// parent
@Component(modules = ParentModule.class)
interface ParentComponent {
// define all public dependencies from Modules
}
@Module
class ParentModule { ... }
// child
@Component(
dependencies = ParentComponent.class,
modules = ChildModule.class
)
interface ChildComponent {
}
@Module
class ChildModule { ... }
ParentComponent parent = DaggerParentComponent.create();
ChildComponent child = DaggerChildComponent.builder()
.parentComponent(parent)
//.childModule(new ChildModule(...))
.build();
"you don’t need to use Dagger in your test at all"
Override bindings by subclassing modules (don’t do this!)
Separate component configurations
Lazy injecting
Producers
...
Video about Dagger 2 (Jake Wharton)