- Fully migrated core cherrypick_generator and submodules to new analyzer element2 system: - Updated all GeneratorForAnnotation overrides to use Element2, ClassElement2, MethodElement2, FieldElement2 and new annotation/metadata access patterns. - Migrated signature and bodies for helpers, parsers, annotation validators, meta utils, and type parsers. - Fixed tests to use readerWriter instead of deprecated reader argument. - Refactored usage of now-absent 'metadata', 'parameters', 'fields', 'methods', 'source', and similar members to use correct *.firstFragment.* or API alternatives. - Cleaned up old imports and unused code. test(generator): update generator integration tests - Updated test calls to use correct TestReaderWriter type and bring test infra in line with current build_runner/testing API. build: update dependencies and pubspec to support latest analyzer/build ecosystem - Raised Dart SDK and package constraints as required for generated code and codegen plugins. - Updated pubspecs in root/examples as needed by build warnings. docs: add plots and assets (new files) BREAKING CHANGE: - Requires Dart 3.8+ and analyzer that supports element2. - All downstream codegen/tests depending on Element API must migrate to Element2 signatures and data model.
CherryPick Workspace
CherryPick Workspace is a modular, open-source dependency injection ecosystem for Dart and Flutter, designed to offer lightweight, flexible, and scalable DI suitable for both backend and frontend (Flutter) development. This monorepo contains the main DI runtime library, annotation helpers, code generation for modular bindings, and seamless Flutter integration.
Packages Overview
-
cherrypick
The core dependency injection library. Supports modular bindings, hierarchical scopes, named and singleton bindings, provider functions (sync/async), runtime parameters, and test-friendly composition.
Intended for use in pure Dart and Flutter projects. -
cherrypick_annotations
A set of Dart annotations (@module,@singleton,@instance,@provide,@named,@params) enabling concise, declarative DI modules and providers, primarily for use with code generation tools. -
cherrypick_generator
A source_gen-based code generator that automatically converts your annotated modules and providers into ready-to-use boilerplate for registration and resolution within your app.
Reduces manual wiring and errors; compatible with build_runner. -
cherrypick_flutter
Adds Flutter-native integration, exposing DI scopes and modules to the widget tree throughCherryPickProviderand enabling dependency management throughout your Flutter app.
Why CherryPick?
- Zero-overhead and intuitive API:
Clean, minimal syntax, strong typing, powerful binding lifecycle control. - High testability:
Supports overriding and hierarchical scope trees. - Both Sync & Async support:
Register and resolve async providers, factories, and dependencies. - Seamless code generation:
Effortless setup with annotations + generator—skip boilerplate! - Works with or without Flutter.
- Production ready:
Robust enough for apps, packages, and server-side Dart. - Extensible & Modular:
Add bindings at runtime, use sub-modules, or integrate via codegen.
Get Started
1. Add dependencies
In your pubspec.yaml:
dependencies:
cherrypick: ^<latest-version>
cherrypick_annotations: ^<latest-version>
dev_dependencies:
build_runner: ^<latest>
cherrypick_generator: ^<latest-version>
For Flutter projects, add:
dependencies:
cherrypick_flutter: ^<latest-version>
2. Write a DI Module (with annotations)
import 'package:cherrypick_annotations/cherrypick_annotations.dart';
import 'package:cherrypick/cherrypick.dart';
@module()
abstract class MyModule extends Module {
@singleton()
ApiClient apiClient() => ApiClient();
@provide()
DataRepository dataRepo(ApiClient client) => DataRepository(client);
@provide()
String greeting(@params() String name) => 'Hello, $name!';
}
3. Generate the bindings
dart run build_runner build
# or for Flutter:
flutter pub run build_runner build
The generator will create a $MyModule class with binding code.
4. Install and Resolve
final scope = CherryPick.openRootScope()
..installModules([$MyModule()]);
final repo = scope.resolve<DataRepository>();
final greeting = scope.resolve<String>(params: 'John'); // 'Hello, John!'
For Flutter, wrap your app with CherryPickProvider for DI scopes in the widget tree:
void main() {
runApp(
CherryPickProvider(child: MyApp()),
);
}
Features at a Glance
- ⚡ Fast, lightweight DI for any Dart/Flutter project
- 🧩 Modular & hierarchical scopes (root, subscopes)
- 🔖 Named/bound/singleton instances out of the box
- 🔄 Sync and async provider support
- ✏️ Runtime parameters for dynamic factory methods
- 🏷️ Code generator for annotation-based DI setup (
cherrypick_generator) - 🕹️ Deep Flutter integration via
CherryPickProvider
Example Usage
Please see:
cherrypick/README.mdfor core DI features and examplescherrypick_flutter/README.mdfor Flutter-specific usagecherrypick_annotations/README.mdandcherrypick_generator/README.mdfor codegen and annotations
Contribution & License
- Contributions: PRs, issues, and feedback are welcome on GitHub.
- License: Apache 2.0 for all packages in this workspace.
Happy Cherry Picking! 🍒