Skip to content

Commit 626c52d

Browse files
trexemDagger Team
authored andcommitted
Internal Changes
RELNOTES=N/A PiperOrigin-RevId: 875340894
1 parent 2d20874 commit 626c52d

1 file changed

Lines changed: 71 additions & 34 deletions

File tree

dev-guide/index.md

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -94,25 +94,56 @@ Classes that lack `@Inject` annotations cannot be constructed by Dagger.
9494

9595
### Satisfying Dependencies
9696

97-
By default, Dagger satisfies each dependency by constructing an instance of the
98-
requested type as described above. When you request a `CoffeeMaker`, it'll
99-
obtain one by calling `new CoffeeMaker()` and setting its injectable fields.
97+
Dagger dependencies are satisfied by declaring bindings. These bindings tell
98+
Dagger how to create new instances of a dependency. The two most common ways to
99+
declare bindings are using `@Inject`-annotated constructors and `@Module`
100+
binding methods.
100101

101-
But `@Inject` doesn't work everywhere:
102+
#### @Inject bindings
102103

103-
* Interfaces can't be constructed.
104-
* Third-party classes can't be annotated.
105-
* Configurable objects must be configured!
104+
Annotating a class's constructor with `@Inject` is the simplest way to define a
105+
binding for a particular type. The `@Inject`-annotated constructor tells Dagger
106+
to use the class's constructor when creating new instances of the class. For
107+
example, if the `CoffeeMaker` class has an `@Inject`-annotated constructor,
108+
Dagger will obtain an instance of it by calling `new CoffeeMaker()`.
106109

107-
For these cases where `@Inject` is insufficient or awkward, use an
108-
[`@Provides`][Provides]-annotated method to satisfy a dependency. The method's
109-
return type defines which dependency it satisfies.
110+
#### @Module bindings
111+
112+
However, `@Inject` doesn't work everywhere:
113+
114+
* Interfaces don't have constructors.
115+
* Third-party classes can't be annotated.
116+
* Configurable objects must be configured!
117+
118+
For these cases where `@Inject` is insufficient or awkward, Dagger uses
119+
**modules** -- classes that contain binding declarations via binding methods.
120+
All binding methods must belong to a module, which is a class annotated with
121+
[`@Module`][Module]. By convention, module classes are named with a `Module`
122+
suffix.
123+
124+
```java
125+
@Module
126+
final class HeaterModule {
127+
128+
/* binding methods go here */
129+
130+
}
131+
```
132+
133+
##### @Provides
134+
135+
Use an [`@Provides`][Provides]-annotated method to satisfy a dependency. The
136+
method's return type defines which dependency it satisfies. By convention,
137+
`@Provides` methods are named with a `provide` prefix.
110138

111139
For example, `provideHeater()` is invoked whenever a `Heater` is required:
112140

113141
```java
114-
@Provides static Heater provideHeater() {
115-
return new ElectricHeater();
142+
@Module
143+
class HeaterModule {
144+
@Provides static Heater provideHeater() {
145+
return new ElectricHeater();
146+
}
116147
}
117148
```
118149

@@ -121,39 +152,49 @@ For example, since `ElectricHeater` has an `@Inject` constructor, the above
121152
method could be written instead as:
122153

123154
```java
124-
@Provides static Heater provideHeater(ElectricHeater heater) {
125-
return heater;
155+
@Module
156+
class HeaterModule {
157+
@Provides static Heater provideHeater(ElectricHeater heater) {
158+
return heater;
159+
}
126160
}
127161
```
128162

129163
This way Dagger takes care of instantiating `ElectricHeater`, and the
130-
`@Provides` method is only used to alias it to the type `Heater`.
164+
`@Provides` method is only used to bind `Heater` to `ElectricHeater`.
131165

132-
In this particular case, we can simplify things further using an `@Binds`
133-
method to define the alias. Unlike `@Provides`, an `@Binds` method is abstract,
134-
and has no implementation:
166+
##### @Binds
167+
168+
In this particular case, we can simplify things further using an `@Binds` method
169+
to declare that binding. Unlike `@Provides`, an `@Binds` method is abstract, and
170+
has no implementation. By convention, `@Binds` methods are named with a `bind`
171+
prefix.
135172

136173
```java
137-
@Binds Heater bindHeater(ElectricHeater impl);
174+
@Module
175+
interface HeaterModule {
176+
@Binds Heater bindHeater(ElectricHeater impl);
177+
}
138178
```
139179

140-
**Note**: Using `@Binds` is the preferred way to define an alias because Dagger only
141-
needs the module at compile time, and can avoid class loading the module at
142-
runtime.
143-
{: .c-callouts__note }
180+
**Note**: Using `@Binds` is the preferred way to declare this kind of binding
181+
because Dagger only needs the module at compile time, and can avoid class
182+
loading the module at runtime. {: .c-callouts__note }
144183

145-
Finally, all `@Provides` and `@Binds` methods must belong to a module. These are
146-
just classes that have an [`@Module`][Module] annotation.
184+
If you have both static `@Provides` and abstract `@Binds` methods, you can put
185+
them both into the same module using an abstract class or interface:
147186

148187
```java
149188
@Module
150189
interface HeaterModule {
151-
@Binds Heater bindHeater(ElectricHeater impl);
190+
@Binds fun bindHeater(impl: ElectricHeater): Heater
191+
192+
@Provides static fun provideElectricHeater() = ElectricHeater()
152193
}
153194
```
154195

155-
Note that in Kotlin, `@Provides` methods can also be declared in the companion
156-
object of an `@Module` class.
196+
In Kotlin, you can get a similar result by putting the `@Binds` methods in an
197+
interface and the `@Provides` methods into its companion object:
157198

158199
```kotlin
159200
@Module
@@ -166,10 +207,6 @@ interface HeaterModule {
166207
}
167208
```
168209

169-
By convention, `@Provides` methods are named with a `provide` prefix, `@Binds`
170-
methods are named with `bind` prefix and module classes are named with a
171-
`Module` suffix.
172-
173210
### Building the Graph
174211

175212
The `@Inject` and `@Provides`-annotated classes form a graph of objects, linked
@@ -309,8 +346,8 @@ interface CoffeeShop {
309346
```
310347

311348
Components may have multiple scope annotations applied. This declares that they
312-
are all aliases to the same scope, and so that component may include scoped
313-
bindings with any of the scopes it declares.
349+
all refer to the same scope, and so that component may include scoped bindings
350+
with any of the scopes it declares.
314351

315352
### Reusable scope
316353

0 commit comments

Comments
 (0)