-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b2bd5fd
commit bb1fc5b
Showing
6 changed files
with
217 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,203 @@ | ||
<!-- | ||
This README describes the package. If you publish this package to pub.dev, | ||
this README's contents appear on the landing page for your package. | ||
# Gate | ||
**Dart/Flutter Dependency injection generator** | ||
|
||
<p align="center"> | ||
<img src="https://github.com/Apparence-io/gate/raw/master/packages/gate_generator/doc/images/cover.png" alt="flutter anchored onboarding screen" /> | ||
</p> | ||
|
||
For information about how to write a good package README, see the guide for | ||
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages). | ||
<p align="center"> | ||
<a href="https://pub.dev/packages/gate_generator"><img src="https://img.shields.io/pub/v/gate_generator" alt="pubdev" style="max-width: 100%;"></a> | ||
<a href="https://github.com/Apparence-io/gate/actions"><img src="https://github.com/Apparence-io/gate/workflows/Dart%20CI/badge.svg" alt="ci" style="max-width: 100%;"></a> | ||
<a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://camo.githubusercontent.com/83d3746e5881c1867665223424263d8e604df233d0a11aae0813e0414d433943/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="License: MIT" data-canonical-src="https://img.shields.io/badge/license-MIT-blue.svg" style="max-width: 100%;"></a> | ||
</p> | ||
|
||
For general information about developing packages, see the Dart guide for | ||
[creating packages](https://dart.dev/guides/libraries/create-library-packages) | ||
and the Flutter guide for | ||
[developing packages and plugins](https://flutter.dev/developing-packages). | ||
--> | ||
|
||
TODO: Put a short description of the package here that helps potential users | ||
know whether this package might be useful for them. | ||
## Motivation | ||
Providing Service should be independant from your pages or other code. | ||
The DI pattern separates the responsibility of creating an object of the service class out of the client class. | ||
Also using code generation we can get rid of the boilerplate part. | ||
|
||
## Features | ||
|
||
TODO: List what your package can do. Maybe include images, gifs, or videos. | ||
- provide Injectable as a singleton | ||
- provide Injectable as a dynamic service | ||
- Inject an Injectable class into another | ||
|
||
## Getting started | ||
install gate with build_runner in you pubspec.yaml | ||
``` | ||
dependencies: | ||
build_runner: ^X.X.X | ||
gate: ^X.X.X | ||
dev_dependencies: | ||
gate_generator: ^X.X.X | ||
``` | ||
> replace X.X.X with last available version on pub.dev. | ||
TODO: List prerequisites and provide or point to information on how to | ||
start using the package. | ||
|
||
## Usage | ||
|
||
TODO: Include short and useful examples for package users. Add longer examples | ||
to `/example` folder. | ||
### 1 - Create a class you want to inject | ||
|
||
```dart | ||
const like = 'sample'; | ||
import 'package:gate/gate.dart'; | ||
@Injectable() | ||
class CoffeeService { | ||
final S1 s1; | ||
CoffeeService._(this.s1); | ||
@Singleton() | ||
factory CoffeeService.simple(S1 s1) => CoffeeService._(s1); | ||
void pump() { | ||
print("CoffeeService it's working"); | ||
} | ||
} | ||
``` | ||
|
||
## Additional information | ||
You just have to | ||
- add @Injectable() above your class | ||
- add @Singleton() or @Provide() above a factory | ||
|
||
### 2 - inject dependency | ||
|
||
We can now inject our Injectables using @Inject annotation. | ||
InjectedChild use | ||
- Type you want to inject | ||
- the name of the factory you want to use (you can have multiple provided factories) | ||
- the attribute name (just in case you want to rename it or make it private...) | ||
|
||
```dart | ||
import 'package:gate_example/gate/gate_provider.dart'; | ||
import 'package:gate_example/gate/coffee_service.dart'; | ||
part 'coffee_page.gate_inject.g.part'; | ||
@Inject(children: [ | ||
InjectedChild(S1, factoryName: "build"), | ||
InjectedChild(CoffeeService, factoryName: "simple", attrName: "coffeeService"), | ||
]) | ||
class CoffeePage extends StatelessWidget { | ||
const CoffeePage({Key? key}) : super(key: key); | ||
@override | ||
Widget build(BuildContext context) { | ||
coffeeService.pump(); | ||
return Container(); | ||
} | ||
} | ||
``` | ||
You can inject as many dependency as you want into your class as long as their are Injectable. | ||
> ```part 'coffee_page.gate_inject.g.part';``` will be be added to your file | ||
> this file will be genererated on next step | ||
> don't forget to import "gate_provider.dart" that is generated next | ||
|
||
### 3 - generate code | ||
Using build runner you can run the command in your shell | ||
```shell | ||
flutter packages pub run build_runner build --delete-conflicting-outputs | ||
``` | ||
|
||
Once build runner is done, you can run your flutter app and use all injected class. | ||
|
||
> If you change your factory or wants to inject other class... just rerun the build_runner :) | ||
## Properties | ||
| Annotation | Description | | ||
|--------------|---------------------------------------------------------------------:| | ||
| Injectable | mark a class as containing Singleton or Provide factories | | ||
| Singleton | mark a factory as a Singleton Injectable | | ||
| Provide | mark a factory as a Dymamic Injectable. Each time you inject will create a new instance of that class | | ||
| Inject | mark a class to inject dependencies | | ||
|
||
|
||
### Inject annotation | ||
| Property | Description | | ||
|-----------------|---------------------------------------------------------------------:| | ||
| children | a list of InjectedChild | | ||
|
||
|
||
### InjectedChild annotation | ||
| Property | Description | | ||
|-----------------|---------------------------------------------------------------------:| | ||
| type | The type to inject | | ||
| factoryName | The factory name to use | | ||
| attrName | *(optionnal)* The attribute name to call it from your class | | ||
|
||
|
||
## Mock an injected dependency for testing | ||
To remplace your service by mocks, you have to set them, before testing. | ||
Gate will generate all methods for you. | ||
|
||
First, declare your mocked services with your prefered libraries. | ||
|
||
Then use the "appProvider" to set mocks. | ||
|
||
Finally, don't forget to reset mocks by setting them to null. | ||
|
||
|
||
```dart | ||
class CoffeeServiceMock extends Mock implements CoffeeService {} | ||
class S1ServiceMock extends Mock implements S1 {} | ||
class S2BServiceMock extends Mock implements S2B {} | ||
class TodoServiceMock extends Mock implements TodoService {} | ||
void main() { | ||
// Initialize mocks | ||
final CoffeeService coffeeServiceMock = CoffeeServiceMock(); | ||
final S1 s1ServiceMock = S1ServiceMock(); | ||
final S2B s2BServiceMock = S2BServiceMock(); | ||
final TodoService todoServiceMock = TodoServiceMock(); | ||
group('Mock injection group', () { | ||
setUp(() { | ||
when(() => coffeeServiceMock.getMenu()).thenReturn("Best menu"); | ||
// Set injected services with mocks | ||
appProvider.setCoffeeServiceSimpleMock(coffeeServiceMock); | ||
appProvider.setS1BuildMock(s1ServiceMock); | ||
appProvider.setS2BBuildMock(s2BServiceMock); | ||
appProvider.setTodoServiceBeanMock(todoServiceMock); | ||
}); | ||
tearDownAll(() { | ||
// Remove mocks from appProvider (real ones will be used) | ||
appProvider.setCoffeeServiceSimpleMock(null); | ||
appProvider.setS1BuildMock(null); | ||
appProvider.setS2BBuildMock(null); | ||
appProvider.setTodoServiceBeanMock(null); | ||
}); | ||
test('Test mocks injection', () async { | ||
expect(appProvider.getCoffeeServiceSimple().getMenu(), | ||
equals('Best menu')); // Mocked returned value | ||
appProvider.setCoffeeServiceSimpleMock(null); | ||
expect(appProvider.getCoffeeServiceSimple().getMenu(), | ||
equals('No menu')); // True value (not mocked) | ||
}); | ||
}); | ||
} | ||
``` | ||
|
||
## Run tests | ||
```bash | ||
dart pub global activate coverage | ||
dart test --coverage="coverage" | ||
format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.packages --report-on=lib | ||
``` | ||
|
||
<hr/> | ||
|
||
## FAQ | ||
*To be done* | ||
|
||
<hr/> | ||
<br><br> | ||
<a href="https://en.apparence.io"><img src="https://github.com/Apparence-io/bart/raw/master/.github/img/logo.png" alt="Apparence.io logo"></a> | ||
<p><small>Developed with 💙 by Apparence.io</small></p> | ||
|
||
TODO: Tell users more about the package: where to find more information, how to | ||
contribute to the package, how to file issues, what response they can expect | ||
from the package authors, and more. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
## 1.0.0 | ||
- upgrade dependencies | ||
- upgrade to 1.0.0 as it's stable | ||
|
||
## 0.0.3+7 | ||
- upgrade dependencies | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// coverage:ignore-file | ||
// ******************************** | ||
// Gate generated file | ||
// Do not modify by hand | ||
// ******************************** | ||
// ignore_for_file: type=lint | ||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target | ||
class AppProvider { | ||
AppProvider._(); | ||
|
||
static final AppProvider instance = AppProvider._(); | ||
} | ||
|
||
final AppProvider appProvider = AppProvider.instance; |