Skip to content

Commit

Permalink
feat: Docs added
Browse files Browse the repository at this point in the history
  • Loading branch information
devtronic committed Dec 30, 2022
1 parent 495d76c commit b199f6d
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ with [catalyst_builder](https://pub.dev/packages/catalyst_builder) and the defau
The main advantage is having dependency injection in all your routes / widgets without wire them the
hard way.

## How does it work?
Check out the "[under the hood](./docs/under-the-hood.md)" doc.


## Installation

- Follow the setup steps for [catalyst_builder](https://pub.dev/packages/catalyst_builder).
Expand Down
9 changes: 9 additions & 0 deletions docs/images/level0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
```mermaid
%%{init:{"theme":"neutral"}}%%
graph LR
CB[Catalyst Builder]
Y[YourApp]-->|resolve|E[Explorator]
E-->|resolved route|Y
Y-->CB
E-->CB
```
Binary file added docs/images/level0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions docs/images/level1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
```mermaid
%%{init:{"theme":"neutral"}}%%
graph LR
subgraph CB[Catalyst Builder]
SP[< I > ServiceProvider]
end
subgraph Y[YourApp]
MA[Flutter Router]
DSP[< G > DefaultServiceProvider]
AR[App Routes]
S1[Screen/Widget 1]
S2[Screen/Widget 2]
DSP-->S1
DSP-->S2
DSP-->AR
AR.-S1
AR.-S2
end
subgraph E[Explorator]
RR[RouteResolver]
RB[< I > RouteBuilder]
RP[< I > RouteProvider]
MRB[MaterialRouteBuilder]
MRB.->RB
RR-->RB
RR-->RP
end
MA-->RR
RR-->SP
DSP.->SP
AR.->RP
DSP-->RR
DSP-->MRB
AR-->SP
```
Binary file added docs/images/level1_full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/level1_partial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 79 additions & 0 deletions docs/under-the-hood.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Under the hood

## Level 0 - Top view
At the top view, the App is organized like this.
You require `explorator` and `catalyst_builder`. `explorator` requires `catalyst_builder` too.


![Top view](./images/level0.png)

## Level 1 - Inner communication
Legend:
- `< G >` = Generated Code
- `< I >` = Interfaces
- `Dashed with arrow head` = Implementation
- `Dashed without arrow head` = Type dependency

The simplified Version of this level looks like this:
![level1_partial.png](images/level1_partial.png)

As you can see, your app only needs to know about the `RouteResolver` and the `RouteProvider` interface.
The RouteResolver is used in `MaterialApp.onGenerateRoute`, the RouteProvider is implemented in our class that provide
the routes.

That view seems a bit incomplete, let's take a look on the full version with generated code.

![level1_full.png](images/level1_full.png)

Let's take a look on the connection between `App Routes` and `Screen/Widget n` / `RouteProvider`.
The `App Routes` class implements the `RouteProvider` interface. That means, that we have to implement the `routes`
property which returns a list of [`RegisteredRoute`](../lib/src/registered_route.dart).
For each route you need to define a path and a builder. The interesting part about this is the builder.
The `builder` is just a method that accepts an instance of a catalyst `ServiceProvider` and returns a default
`WidgetBuilder` function.
That means, we can use the given provider to resolve our `Screen/Widget n` without constructing it manually.
Since the `App Routes` class is not imported anywhere (ignore generated code 😉), the coupling is not worth mentioning.

As you noted, there is a connection between `DefaultServiceProvider` (DSP) and `App Routes`. That means, that the
`App Routes` class must be decorated with `@Service(tags: [#routeProvider])`.

-----

Next step: take a look on the connection between `RouteResolver` and `RouteProvider` / `ServiceProvider`.

The [`RouteResolver`](../lib/src/route_resolver.dart) expects in the constructor a `List<RouteProvider>`. If you take
a look in the code, you can see, that the constructor parameter is decorated with `@Inject(tag: #routeProvider)`.

Now you can put two and two together. The `ServiceProvider` takes all services that are tagged with `#routeProvider`,
including our `App Routes` class, and inject it as a list to the `RouteResolver`.

-----

That's already most of the magic. Let's take a look how routes are resolved.

Since the `RouteResolver` is decorated with `@Service`, your `ServiceProvider` can construct this class.

And that's exactly what happens in this piece of code.
```dart
Widget build(BuildContext context) {
return MaterialApp(
// 1. We resolve the `RouteResolver` from the DSP
// 2. Tell the Flutter router "use `resolveRoute` to generate routes"
onGenerateRoute: _provider.resolve<RouteResolver>().resolveRoute,
);
}
```

The `RouteResolver.resolveRoute` looks more complicated as it's.
1. It accepts a `RouteSettings` object, that contains a `name` (=path) and `arguments`
2. The `name` is the `path` of our `RegisteredRoute`.
- The `RegisteredRoute` creates a Regex from this path.
3. Then it iterates over all `RegisteredRoute`s (passed in the constructor) and check if the `name` match against the regex.
4. If it's a match, the method extracts the path variables and creates a sub-`ServiceProvider`.
- The sub-`ServiceProvider` contains additional services:
- [`RouteArguments`](../lib/src/route_arguments.dart)
- `RouteSettings`
5. Using the builder from the `RegisteredRoute` to construct the widget. We pass the sub-`ServiceProvider` as the `ServiceProvider`.
6. Using the `RouteBuilder` to construct and return a Flutter route.

Not that complicated, right? 😅

0 comments on commit b199f6d

Please sign in to comment.