2025-09-08 17:16:51 +03:00
[](https://github.com/pese-git/cherrypick/actions/workflows/pipeline.yml)
2025-09-09 13:22:39 +03:00
[](https://app.netlify.com/projects/cherrypick-di/deploys)
2025-09-08 17:16:51 +03:00
---
2025-05-22 16:06:38 +03:00
# Cherrypick Generator
2025-05-14 12:53:51 +03:00
2025-05-23 17:23:22 +03:00
**Cherrypick Generator** is a Dart code generation library for automating dependency injection (DI) boilerplate. It processes classes and fields annotated with [cherrypick_annotations ](https://pub.dev/packages/cherrypick_annotations ) and generates registration code for services, modules, and field injection for classes marked as `@injectable` . It supports advanced DI features such as scopes, named bindings, parameters, and asynchronous dependencies.
2025-05-14 12:53:51 +03:00
2025-05-18 15:43:02 +03:00
---
2025-05-14 12:53:51 +03:00
## Features
2025-05-23 17:23:22 +03:00
- **Automatic Field Injection:**
Detects classes annotated with `@injectable()` , and generates mixins to inject all fields annotated with `@inject()` , supporting scope and named qualifiers.
2025-05-22 16:06:38 +03:00
2025-05-23 17:23:22 +03:00
- **Module and Service Registration:**
For classes annotated with `@module()` , generates service registration code for methods using annotations such as `@provide` , `@instance` , `@singleton` , `@named` , and `@params` .
2025-05-22 16:06:38 +03:00
2025-05-23 17:23:22 +03:00
- **Scope & Named Qualifier Support:**
Supports advanced DI features:
• Field-level scoping with `@scope('scopename')`
• Named dependencies via `@named('value')`
2025-05-22 16:06:38 +03:00
- **Synchronous & Asynchronous Support:**
2025-05-23 17:23:22 +03:00
Handles both synchronous and asynchronous services (including `Future<T>` ) for both field injection and module registration.
2025-05-22 16:06:38 +03:00
2025-05-23 17:23:22 +03:00
- **Parameters and Runtime Arguments:**
Recognizes and wires both injected dependencies and runtime parameters using `@params` .
2025-05-22 16:06:38 +03:00
2025-05-23 17:23:22 +03:00
- **Error Handling:**
Validates annotations at generation time. Provides helpful errors for incorrect usage (e.g., using `@injectable` on non-class elements).
2025-05-14 12:53:51 +03:00
2025-05-18 15:43:02 +03:00
---
2025-05-14 12:53:51 +03:00
2025-05-18 15:43:02 +03:00
## How It Works
2025-05-14 12:53:51 +03:00
2025-05-23 17:23:22 +03:00
### 1. Annotate your code
2025-05-22 16:06:38 +03:00
2025-05-23 17:23:22 +03:00
Use annotations from [cherrypick_annotations ](https://pub.dev/packages/cherrypick_annotations ):
2025-05-22 16:06:38 +03:00
2025-05-23 17:23:22 +03:00
- `@injectable()` — on classes to enable field injection
- `@inject()` — on fields to specify they should be injected
- `@scope()` , `@named()` — on fields or parameters for advanced wiring
- `@module()` — on classes to mark as DI modules
- `@provide` , `@instance` , `@singleton` , `@params` — on methods and parameters for module-based DI
2025-05-14 12:53:51 +03:00
2025-05-23 17:23:22 +03:00
### 2. Run the generator
Use `build_runner` to process your code and generate `.module.cherrypick.g.dart` and `.inject.cherrypick.g.dart` files.
### 3. Use the output in your application
- For modules: Register DI providers using the generated `$YourModule` class.
- For services: Enable field injection on classes using the generated mixin.
---
## Field Injection Example
Given the following:
```dart
import 'package:cherrypick_annotations/cherrypick_annotations.dart';
@injectable ()
class MyWidget with _$MyWidget {
@inject ()
late final AuthService auth;
@inject ()
@scope ('profile')
late final ProfileManager manager;
@inject ()
@named ('special')
late final ApiClient specialApi;
}
```
**The generator will output (simplified):**
```dart
mixin _$MyWidget {
void _inject(MyWidget instance) {
instance.auth = CherryPick.openRootScope().resolve< AuthService > ();
instance.manager = CherryPick.openScope(scopeName: 'profile').resolve< ProfileManager > ();
instance.specialApi = CherryPick.openRootScope().resolve< ApiClient > (named: 'special');
}
}
```
You can then mix this into your widget to enable automatic DI at runtime.
2025-05-22 16:06:38 +03:00
---
2025-05-23 17:23:22 +03:00
## Module Registration Example
2025-05-22 16:06:38 +03:00
2025-05-23 17:23:22 +03:00
Given:
2025-05-14 12:53:51 +03:00
```dart
2025-05-18 15:43:02 +03:00
import 'package:cherrypick_annotations/cherrypick_annotations.dart';
@module ()
2025-05-22 16:06:38 +03:00
class MyModule {
@singleton
@instance
2025-05-23 17:23:22 +03:00
AuthService provideAuth(Api api);
2025-05-22 16:06:38 +03:00
@provide
2025-05-23 17:23:22 +03:00
@named ('logging')
Future< Logger > provideLogger(@params Map< String , dynamic > args);
2025-05-18 15:43:02 +03:00
}
```
2025-05-23 17:23:22 +03:00
**The generator will output (simplified):**
2025-05-18 15:43:02 +03:00
```dart
2025-05-22 16:06:38 +03:00
final class $MyModule extends MyModule {
2025-05-18 15:43:02 +03:00
@override
void builder(Scope currentScope) {
2025-05-23 17:23:22 +03:00
bind< AuthService > ()
.toInstance(provideAuth(currentScope.resolve< Api > ()))
2025-05-22 16:06:38 +03:00
.singleton();
2025-05-23 17:23:22 +03:00
bind< Logger > ()
.toProvideAsyncWithParams((args) => provideLogger(args))
.withName('logging');
2025-05-18 15:43:02 +03:00
}
}
```
---
2025-05-23 17:23:22 +03:00
## Key Points
2025-05-18 15:43:02 +03:00
2025-05-23 17:23:22 +03:00
- **Rich Annotation Support:**
Mix and match field, parameter, and method annotations for maximum flexibility.
- **Scope and Named Resolution:**
Use `@scope('...')` and `@named('...')` to precisely control where and how dependencies are wired.
- **Async/Synchronous:**
The generator distinguishes between sync (`resolve<T>` ) and async (`resolveAsync<T>` ) dependencies.
- **Automatic Mixins:**
For classes with `@injectable()` , a mixin is generated that injects all relevant fields (using constructor or setter).
- **Comprehensive Error Checking:**
Misapplied annotations (e.g., `@injectable()` on non-class) produce clear build-time errors.
2025-05-18 15:43:02 +03:00
2025-05-22 16:06:38 +03:00
---
2025-05-18 15:43:02 +03:00
2025-05-22 16:06:38 +03:00
## Usage
2025-05-18 15:43:02 +03:00
2025-05-23 17:23:22 +03:00
1. **Add dependencies**
2025-05-22 16:06:38 +03:00
```yaml
dependencies:
2025-05-23 17:23:22 +03:00
cherrypick_annotations: ^latest
2025-05-18 15:43:02 +03:00
2025-05-22 16:06:38 +03:00
dev_dependencies:
2025-05-23 17:23:22 +03:00
cherrypick_generator: ^latest
2025-05-22 16:06:38 +03:00
build_runner: ^2.1.0
```
2025-05-23 17:23:22 +03:00
2. **Annotate your classes and modules as above**
2025-05-22 16:06:38 +03:00
2025-05-23 17:23:22 +03:00
3. **Run the generator**
```shell
2025-05-22 16:06:38 +03:00
dart run build_runner build
2025-05-23 17:23:22 +03:00
# or, if using Flutter:
2025-05-22 16:06:38 +03:00
flutter pub run build_runner build
```
2025-05-14 12:53:51 +03:00
2025-05-23 17:23:22 +03:00
4. **Use generated code**
2025-05-18 15:43:02 +03:00
2025-05-23 17:23:22 +03:00
- Import the generated `.inject.cherrypick.g.dart` or `.cherrypick.g.dart` files where needed
2025-05-18 15:43:02 +03:00
2025-05-23 17:23:22 +03:00
---
2025-05-18 15:43:02 +03:00
2025-05-23 17:23:22 +03:00
## Advanced Usage
2025-05-18 15:43:02 +03:00
2025-05-23 17:23:22 +03:00
- **Combining Modules and Field Injection:**
It's possible to mix both style of DI — modules for binding, and field injection for consuming services.
- **Parameter and Named Injection:**
Use `@named` on both provider and parameter for named registration and lookup; use `@params` to pass runtime arguments.
2025-05-22 16:06:38 +03:00
- **Async Factories:**
2025-05-23 17:23:22 +03:00
Methods returning Future< T > generate async bindings and async field resolution logic.
2025-05-18 15:43:02 +03:00
---
2025-05-22 16:06:38 +03:00
## Developer Notes
2025-05-18 15:43:02 +03:00
2025-05-23 17:23:22 +03:00
- The generator relies on the Dart analyzer, `source_gen` , and `build` packages.
- All classes and methods are parsed for annotations.
- Improper annotation usage will result in generator errors.
2025-05-18 15:43:02 +03:00
---
2025-05-22 16:06:38 +03:00
## License
2025-05-18 15:43:02 +03:00
2025-05-22 16:06:38 +03:00
```
Licensed under the Apache License, Version 2.0
```
2025-05-18 15:43:02 +03:00
---
2025-05-22 16:06:38 +03:00
## Contribution
2025-05-23 17:23:22 +03:00
Pull requests and issues are welcome! Please open GitHub issues or submit improvements.
---
2025-05-14 12:53:51 +03:00