Skip to content

Commit 42c68e2

Browse files
qk7bwolfenrainMayaa-salestiagoJochum van der Ploeg
authored
docs(dependency injection): Add a section about ordering providers (#1218)
Co-authored-by: Jochum van der Ploeg <[email protected]> Co-authored-by: Mayaa-s <[email protected]> Co-authored-by: Alejandro Santiago <[email protected]> Co-authored-by: Jochum van der Ploeg <[email protected]>
1 parent 3ec5c97 commit 42c68e2

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

docs/docs/basics/dependency-injection.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,100 @@ Middleware cachedAsyncGreetingProvider() {
158158
```
159159

160160
With the above implementations, the greeting will only be computed once and the cached value will be used for the duration of the application lifecycle.
161+
162+
### Order matters
163+
164+
In a real life application you will find yourself adding multiple `providers` to your project.
165+
166+
Some `providers` **will depend** on others, as with any application relying on dependency injection.
167+
168+
Let's take the example of a `Car` that depends on a `Wheel`.
169+
170+
We will have two `providers` where the second one depends on the first one for it to work:
171+
172+
1. A first `provider`, called `wheelMiddlewareProvider`, that creates the `Wheel` object
173+
174+
```dart
175+
final _wheel = Wheel();
176+
177+
/// Provides a [Wheel] instance.
178+
Middleware wheelMiddlewareProvider() {
179+
return provider<Wheel>(
180+
(_) => _wheel,
181+
);
182+
}
183+
```
184+
185+
2. A second `provider`, called `carMiddlewareProvider`, that provides a `Car` object
186+
187+
```dart
188+
class Car {
189+
final Wheel wheel;
190+
191+
Car({
192+
required this.wheel;
193+
});
194+
}
195+
196+
/// Middleware to create the Car object
197+
Middleware carMiddlewareProvider() {
198+
return provider<Car>(
199+
(context) => Car(
200+
wheel: context.read<Wheel>(),
201+
),
202+
);
203+
}
204+
```
205+
206+
At this point, it seems clear that `carMiddlewareProvider` depends on `wheelMiddlewareProvider`.
207+
208+
When you try to access the instance of `Car` using `context.read<Car>()`, here is what will happen:
209+
210+
1. _Dart Frog_ will try to create the instance and return it. To do so, it will create a `Car` object and to fulfill its `wheel` parameter
211+
2. It will "look above" in the dependency graph for a provider of `Wheel`
212+
3. It will find it with `wheelMiddlewareProvider`, and so on.
213+
214+
This is how dependency injections works, but let's clarify what "look above" means.
215+
216+
We have to tell Dart Frog how to build a `Wheel` **before** it builds a `Car`. We do that by defining the order of the providers.
217+
218+
:::tip
219+
In Dart Frog, dependencies are resolved from **bottom** to **top**
220+
:::
221+
222+
So if provider `B` depends on provider `A`, you will have to declare them as followed:
223+
224+
```dart
225+
Handler middleware(Handler handler) {
226+
return handler
227+
.use(B())
228+
.use(A())
229+
}
230+
```
231+
232+
In the example we gave at the beginning where `carMiddlewareProvider` depends on `wheelMiddlewareProvider` we know it will work when we provided them like so:
233+
234+
```dart
235+
Handler middleware(Handler handler) {
236+
return handler
237+
.use(carMiddlewareProvider())
238+
.use(wheelMiddlewareProvider())
239+
}
240+
```
241+
242+
But if we change the order of the providers it will not work:
243+
244+
```dart
245+
Handler middleware(Handler handler) {
246+
return handler
247+
// This won't work because Dart Frog is bottom top
248+
.use(wheelMiddlewareProvider())
249+
.use(carMiddlewareProvider())
250+
}
251+
```
252+
253+
:::note
254+
Right now, there is an issue about this [fix: Improve dependency injection order #745](https://github.com/VeryGoodOpenSource/dart_frog/issues/745) because some other DI frameworks are working top to bottom and dart_frog is bottom to top.
255+
256+
So you might want to keep that in mind for future releases, but as it would be a breaking change, the release version will reflect this.
257+
:::

0 commit comments

Comments
 (0)