Skip to content

Commit

Permalink
Merge pull request #9 from RicardoRB/0.5.1-alpha
Browse files Browse the repository at this point in the history
0.5.1 alpha
  • Loading branch information
RicardoRB committed Nov 6, 2023
2 parents 1e85084 + 260d33b commit e38d3ef
Show file tree
Hide file tree
Showing 276 changed files with 1,769 additions and 436 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ $ dart create -t console your_project_name

```yaml
dependencies:
dartness_server: ^0.5.0-alpha
dartness_server: ^0.5.1-alpha

dev_dependencies:
build_runner: ^2.2.0
dartness_generator: ^0.4.6-alpha
dartness_generator: ^0.5.2-alpha
```
Expand Down
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ $ dart create -t console your_project_name

```yaml
dependencies:
dartness_server: ^0.5.0-alpha
dartness_server: ^0.5.1-alpha

dev_dependencies:
build_runner: ^2.2.0
dartness_generator: ^0.4.6-alpha
dartness_generator: ^0.5.2-alpha
```
Expand Down
2 changes: 2 additions & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
- Overview
- [First steps](first_steps.md)
- [Controllers](controllers.md)
- [Providers](providers.md)
- [Modules](modules.md)
- [Middlewares](middleware.md)
- [Interceptors](interceptor.md)
- [Exceptions](exceptions.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ part 'city_controller.g.dart';
@Controller('/cities')
class CitiesController {
@Get('/<id>')
String findById(@PathParam() id) {
String findById(@PathParam() int id) {
return 'This action returns a city with id: $id';
}
}
Expand Down
110 changes: 110 additions & 0 deletions docs/custom_providers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Custom providers

Custom providers typically refer to services or objects that you create and configure yourself to be used within your
application. These providers are not part of the core `Dartness` framework or provided by any third-party libraries;
instead, you define them to suit your specific needs. Custom providers can include services, repositories, factories, or
any other objects that your application requires for its functionality.

Custom providers are an essential part of the Dartness dependency injection system, which allows you to manage and
inject dependencies throughout your application. By creating custom providers, you can decouple various parts of your
application and make it more modular and maintainable.

## Standard providers

Let's take a closer look at the `ModuleMetadata` class. In `app.dart`, we declare in our section [providers]:

```dart
@Application(
module: Module(
metadata: ModuleMetadata(
controllers: [
ProviderMetadata(
classType: CitiesController,
),
],
providers: [
ProviderMetadata(
classType: CitiesService,
),
],
),
),
)
class App {}
```

The providers attribute takes an array of providers. We've supplied those providers via a list of `ProviderMetadata`
class that we can specify by the attribute `classType` the class that we want to have as provider.

## Custom providers

What happens when your requirements go beyond those offered by Standard providers? Here are a few examples.

### Factory providers

The `useFactory` syntax allows for creating providers dynamically. The actual provider will be supplied by the value
returned from a factory function. The factory function can be as simple or complex as needed. A simple factory may not
depend on any other providers. A more complex factory can itself inject other providers it needs to compute its result.
For the latter case, the factory provider syntax has a pair of related mechanisms:

```dart
Dio createDio() => Dio();
CitiesService createCitiesService(Dio dio) => CitiesService(dio);
@Application(
module: Module(
metadata: ModuleMetadata(
controllers: [
ProviderMetadata(
classType: CitiesController,
),
],
providers: [
ProviderMetadata(
classType: Dio,
useFactory: createDio,
),
ProviderMetadata(
classType: CitiesService,
useFactory: createCitiesService,
),
],
),
),
)
class App {}
```

> **_NOTE:_** As current limitations of `dart` language, it is not allow to use `const` `Function` as part of the
> attribute, in order to avoid it you need to declare the `Function` as global as we saw in the previous example.
**BAD!!!**

```dart
@Application(
module: Module(
metadata: ModuleMetadata(
controllers: [
ProviderMetadata(
classType: CitiesController,
),
],
providers: [
ProviderMetadata(
classType: Dio,
// this is not going to work
useFactory: () => Dio(),
),
ProviderMetadata(
classType: CitiesService,
// this is not going to work
useFactory: (Dio dio) => CitiesService(dio),
),
],
),
),
)
class App {}
```
4 changes: 2 additions & 2 deletions docs/first_steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ $ dart create -t console your_project_name

```yaml
dependencies:
dartness_server: ^0.5.0-alpha
dartness_server: ^0.5.1-alpha

dev_dependencies:
build_runner: ^2.2.0
dartness_generator: ^0.4.6-alpha
dartness_generator: ^0.5.2-alpha
```
### 2. Create the file in "bin/app.dart" or whatever file that you consider that you root application is.
Expand Down
80 changes: 80 additions & 0 deletions docs/modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Modules

A module is a class that provides metadata that Dartness makes use
of to organize the application structure.

Each application has at least one module, a root module. The root module is the starting point Dartness uses to build
the application graph - the internal data structure Dartness uses to resolve module and provider relationships and
dependencies. While very small applications may theoretically have just the root module, this is not the typical case.
We want to emphasize that modules are strongly recommended as an effective way to organize your components. Thus, for
most applications, the resulting architecture will employ multiple modules, each encapsulating a closely related set of
capabilities.

The `Module` class has properties to describe the module:

| Attribute | Description |
|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `providers` | the providers that will be instantiated by the Nest injector and that may be shared at least across this module |
| `controllers` | the set of controllers defined in this module which have to be instantiated |
| `imports` | the list of imported modules that export the providers which are required in this module |
| `exports` (under construction) | the subset of providers that are provided by this module and should be available in other modules which import this module. You can use either the provider itself or just its token (provide value) |

## Feature modules

The `CitiesController` and `CitiesService` belong to the same application domain. As they are closely related, it makes
sense to move them into a feature module. A feature module simply organizes code relevant for a specific feature,
keeping code organized and establishing clear boundaries. This helps us manage complexity and develop with SOLID
principles, especially as the size of the application and/or team grow.

To demonstrate this, we'll create the `CitiesModule`.

```dart
const cityModule = Module(
metadata: ModuleMetadata(
controllers: [
ProviderMetadata(
classType: CityController,
),
],
providers: [
ProviderMetadata(
classType: CityService,
),
],
),
);
```

Above, we defined the `CitiesModule` in the `cities_module.dart` file, and moved everything related to this module into
the cities' directory. The last thing we need to do is import this module into the root module (the AppModule, defined
in the `app.dart` file).

```dart
import 'cities/city_module.dart';
@Application(
module: Module(
metadata: ModuleMetadata(
imports: [cityModule],
),
),
)
class App {}
```

Here is how our directory structure looks now:

```
├── src
│ ├── cities
│ │ ├── cities_service.dart
│ │ ├── cities_service.g.dart
│ │ ├── cities_controller.dart
│ │ ├── cities_controller.g.dart
│ │ ├── cities_module.dart
│ ├── app.dart
│ ├── app.g.dart
```

In this example our module is global since we declared it in a global variable.
83 changes: 83 additions & 0 deletions docs/providers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Providers

Providers refer to a core concept related to dependency injection. Providers are responsible for creating and managing
various dependencies and services that your application needs. These dependencies can include things like services,
repositories, configuration settings, database connections, and more. Dartness uses providers as a fundamental building
block for organizing and maintaining the components of your application.

## Services

To begin, we can create a basic `CitiesService` that will handle data storage and retrieval. This service is intended to
be utilized by the `CitiesController` and is a suitable candidate for registration as a provider.

```dart
class CitiesService {
final List<City> cities = [];
void create(City city) {
cities.add(city);
}
List<City> findAll() {
return cities;
}
}
```

The `CitiesService` is a straightforward class with a single property and two methods. Currently, there is no need to
indicate that the class should be injectable.

Now that we have a service class to retrieve cities, let's use it inside the `CitiesController`:

```dart
@Controller('cities')
class CatsController {
final CitiesService _citiesService;
CatsController(this._citiesService);
@Post()
void create(@Body() City city) {
catsService.create(city);
}
@Get()
List<City> findAll() {
return catsService.findAll();
}
}
```

The `CitiesService` is injected through the class constructor.

# Provider registration

Now that we have defined a provider (`CitiesService`), and we have a consumer of that service (`CitiesController`), we
need to
register the service with Dartness so that it can perform the injection. We do this by editing our module file (
app.dart) and adding the service to the `providers` attribute of the `@Application()` annotation using
the `ModuleMetadata` class in order to structure the metadata and the `ProviderMetadata` class to structure our
provider.

```dart
@Application(
module: Module(
metadata: ModuleMetadata(
controllers: [
ProviderMetadata(
classType: CitiesController,
),
],
providers: [
ProviderMetadata(
classType: CitiesService,
),
],
),
),
)
class App {}
```

Dartness will now be able to resolve the dependencies of the `CitiesController` class.

21 changes: 3 additions & 18 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,15 @@ $ dart create -t console your_project_name

```yaml
dependencies:
dartness_server: ^0.5.0-alpha
dartness_server: ^0.5.1-alpha
dev_dependencies:
dartness_generator: ^0.4.6-alpha
dartness_generator: ^0.5.2-alpha
```
### 2.Create the file in "src/app.dart"
```dart
@Application(
module: Module(
metadata: ModuleMetadata(
controllers: [],
providers: [],
exports: [],
imports: [],
),
),
options: DartnessApplicationOptions(
port: int.fromEnvironment(
'port',
defaultValue: 8080,
),
),
)
@Application()
class App {}
```

Expand Down
2 changes: 1 addition & 1 deletion examples/dartness_flutter_melos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ $ dart run servers/my_server/bin/my_server.dart
#### Run Flutter

```bash
$ flutter run apps/my_app/lib/main.dart
$ flutter run apps/my_app/lib/app.dart
```

## Conclusion
Expand Down
2 changes: 1 addition & 1 deletion examples/dartness_flutter_melos/apps/my_app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ Flutter app with Dartness as backend example.
## Run the app

```bash
$ flutter run lib/main.dart
$ flutter run lib/app.dart
```
2 changes: 1 addition & 1 deletion examples/dartness_flutter_melos/apps/my_app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.3
flutter_lints: ^3.0.0

flutter:
uses-material-design: true
Loading

0 comments on commit e38d3ef

Please sign in to comment.