diff --git a/doc/annotations_en.md b/doc/annotations_en.md new file mode 100644 index 0000000..6d63aa5 --- /dev/null +++ b/doc/annotations_en.md @@ -0,0 +1,140 @@ +# DI Code Generation with Annotations (CherryPick) + +CherryPick enables smart, fully-automated dependency injection (DI) for Dart/Flutter via annotations and code generation. +This eliminates boilerplate and guarantees correctness—just annotate, run the generator, and use! + +--- + +## 1. How does it work? + +You annotate classes, fields, and modules using [cherrypick_annotations]. +The [cherrypick_generator] processes these, generating code that registers your dependencies and wires up fields or modules. + +You then run: +```sh +dart run build_runner build --delete-conflicting-outputs +``` +— and use the generated files in your app. + +--- + +## 2. Supported Annotations + +| Annotation | Where | Purpose | +|-------------------|-----------------|----------------------------------------------------------| +| `@injectable()` | class | Enables auto field injection; mixin will be generated | +| `@inject()` | field | Field will be injected automatically | +| `@scope()` | field/param | Use a named scope when resolving this dep | +| `@named()` | field/param | Bind/resolve a named interface implementation | +| `@module()` | class | Marks as a DI module (methods = providers) | +| `@provide` | method | Registers a type via this provider method | +| `@instance` | method | Registers a direct instance (like singleton/factory) | +| `@singleton` | method/class | The target is a singleton | +| `@params` | param | Accepts runtime/constructor params for providers | + +**You can combine annotations as needed for advanced use-cases.** + +--- + +## 3. Practical Examples + +### A. Field Injection (recommended for widgets/classes) + +```dart +import 'package:cherrypick_annotations/cherrypick_annotations.dart'; + +@injectable() +class MyWidget with _$MyWidget { // the generated mixin + @inject() + late final AuthService auth; + + @inject() + @scope('profile') + late final ProfileManager profile; + + @inject() + @named('special') + late final ApiClient specialApi; +} +``` + +- After running build_runner, the mixin _$MyWidget is created. +- Call `MyWidget().injectFields();` (method name may be `_inject` or similar) to populate the fields! + +### B. Module Binding (recommended for global app services) + +```dart +@module() +abstract class AppModule extends Module { + @singleton + AuthService provideAuth(Api api) => AuthService(api); + + @provide + @named('logging') + Future provideLogger(@params Map args) async => ... +} +``` + +- Providers can return async(`Future`) or sync. +- `@singleton` = one instance per scope. + +--- + +## 4. Using the Generated Code + +1. Add to your `pubspec.yaml`: + + ```yaml + dependencies: + cherrypick: any + cherrypick_annotations: any + + dev_dependencies: + cherrypick_generator: any + build_runner: any + ``` + +2. Import generated files (e.g. `app_module.module.cherrypick.g.dart`, `your_class.inject.cherrypick.g.dart`). + +3. Register modules: + + ```dart + final scope = openRootScope() + ..installModules([$AppModule()]); + ``` + +4. For classes with auto-injected fields, mix in the generated mixin and call the injector: + + ```dart + final widget = MyWidget(); + widget.injectFields(); // or use the mixin's helper + ``` + +5. All dependencies are now available and ready to use! + +--- + +## 5. Advanced Features + +- **Named and Scoped dependencies:** use `@named`, `@scope` on fields/methods and in resolve(). +- **Async support:** Providers or injected fields can be Future (resolveAsync). +- **Runtime parameters:** Decorate a parameter with `@params`, and use `resolve(params: ...)`. +- **Combining strategies:** Mix field injection (`@injectable`) and module/provider (`@module` + methods) in one app. + +--- + +## 6. Troubleshooting + +- Make sure all dependencies are annotated, imports are correct, and run `build_runner` on every code/DI change. +- Errors in annotation usage (e.g. `@singleton` on non-class/method) will be shown at build time. +- Use the `.g.dart` files directly—do not edit them by hand. + +--- + +## 7. References + +- [Cherrypick Generator README (extended)](../cherrypick_generator/README.md) +- Example: `examples/postly` +- [API Reference](../cherrypick/doc/api/) + +--- diff --git a/doc/annotations_ru.md b/doc/annotations_ru.md new file mode 100644 index 0000000..cca45df --- /dev/null +++ b/doc/annotations_ru.md @@ -0,0 +1,137 @@ +# Генерация DI-кода через аннотации (CherryPick) + +CherryPick позволяет получить умный и полностью автоматизированный DI для Dart/Flutter на основе аннотаций и генерации кода. +Это убирает boilerplate — просто ставьте аннотации, запускайте генератор и используйте результат! + +--- + +## 1. Как это работает? + +Вы размечаете классы, поля и модули с помощью [cherrypick_annotations]. +[cherrypick_generator] анализирует их и создаёт код для регистрации зависимостей и подстановки полей или модулей. + +Далее — запускайте: +```sh +dart run build_runner build --delete-conflicting-outputs +``` +— и используйте сгенерированные файлы в проекте. + +--- + +## 2. Поддерживаемые аннотации + +| Аннотация | Где применить | Значение | +|--------------------|------------------|------------------------------------------------------------| +| `@injectable()` | класс | Включает автоподстановку полей, генерируется mixin | +| `@inject()` | поле | Поле будет автоматически подставлено DI | +| `@scope()` | поле/параметр | Использовать определённый scope при разрешении | +| `@named()` | поле/параметр | Именованный биндинг для интерфейсов/реализаций | +| `@module()` | класс | Класс как DI-модуль (методы — провайдеры) | +| `@provide` | метод | Регистрирует тип через этот метод-провайдер | +| `@instance` | метод | Регистрирует как прямой инстанс (singleton/factory, как есть)| +| `@singleton` | метод/класс | Синглтон (один экземпляр на scope) | +| `@params` | параметр | Пробрасывает параметры рантайм/конструктора в DI | + +Миксуйте аннотации для сложных сценариев! + +--- + +## 3. Примеры использования + +### A. Field Injection (рекомендуется для виджетов/классов) + +```dart +import 'package:cherrypick_annotations/cherrypick_annotations.dart'; + +@injectable() +class MyWidget with _$MyWidget { + @inject() + late final AuthService auth; + + @inject() + @scope('profile') + late final ProfileManager profile; + + @inject() + @named('special') + late final ApiClient specialApi; +} +``` +- После build_runner появится mixin _$MyWidget. +- Вызовите `MyWidget().injectFields();` (или соответствующий метод из mixin), чтобы заполнить поля. + +### B. Binding через модуль (вариант для глобальных сервисов) + +```dart +@module() +abstract class AppModule extends Module { + @singleton + AuthService provideAuth(Api api) => AuthService(api); + + @provide + @named('logging') + Future provideLogger(@params Map args) async => ... +} +``` +- Методы-провайдеры поддерживают async (Future) и singleton. + +--- + +## 4. Использование сгенерированного кода + +1. В `pubspec.yaml`: + + ```yaml + dependencies: + cherrypick: any + cherrypick_annotations: any + + dev_dependencies: + cherrypick_generator: any + build_runner: any + ``` + +2. Импортируйте сгенерированные файлы (`app_module.module.cherrypick.g.dart`, `your_class.inject.cherrypick.g.dart`). + +3. Регистрируйте модули так: + + ```dart + final scope = openRootScope() + ..installModules([$AppModule()]); + ``` + +4. Для классов с автоподстановкой полей (field injection): используйте mixin и вызовите injector: + + ```dart + final widget = MyWidget(); + widget.injectFields(); // или эквивалентный метод из mixin + ``` + +5. Все зависимости готовы к использованию! + +--- + +## 5. Расширенные возможности + +- **Именованные и scope-зависимости:** используйте `@named`, `@scope` в полях/методах/resolve. +- **Async:** Провайдеры и поля могут быть Future (resolveAsync). +- **Параметры рантайм:** через `@params` прямо к провайдеру: `resolve(params: ...)`. +- **Комбинированная стратегия:** можно смешивать field injection и модульные провайдеры в одном проекте. + +--- + +## 6. Советы и FAQ + +- Проверьте аннотации, пути import и запускайте build_runner после каждого изменения DI/кода. +- Ошибки применения аннотаций появляются на этапе генерации. +- Никогда не редактируйте .g.dart файлы вручную. + +--- + +## 7. Полезные ссылки + +- [README по генератору](../cherrypick_generator/README.md) +- Пример интеграции: `examples/postly` +- [API Reference](../cherrypick/doc/api/) + +---