From 52bc66f2f9378a51f5d99405f9f7a32ec1247faa Mon Sep 17 00:00:00 2001 From: Sergey Penkovsky Date: Fri, 23 May 2025 17:27:40 +0300 Subject: [PATCH] update documentaions --- cherrypick_annotations/README.md | 96 ++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 12 deletions(-) diff --git a/cherrypick_annotations/README.md b/cherrypick_annotations/README.md index 91deca2..9b04465 100644 --- a/cherrypick_annotations/README.md +++ b/cherrypick_annotations/README.md @@ -2,7 +2,7 @@ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) -A lightweight set of Dart annotations designed for dependency injection (DI) frameworks and code generation, inspired by modern approaches like Dagger and Injectable. Works best in tandem with [`cherrypick_generator`](https://pub.dev/packages/cherrypick_generator). +A lightweight set of Dart annotations for dependency injection (DI) frameworks and code generation, inspired by modern approaches like Dagger and Injectable. Optimized for use with [`cherrypick_generator`](https://pub.dev/packages/cherrypick_generator). --- @@ -10,10 +10,13 @@ A lightweight set of Dart annotations designed for dependency injection (DI) fra - **@module** – Marks a class as a DI module for service/provider registration. - **@singleton** – Declares that a method or class should be provided as a singleton. -- **@instance** – Marks a method or class so that a new instance is provided on each request (not a singleton). -- **@provide** – Marks a method whose return value should be registered as a provider, supporting dependency injection into parameters. -- **@named** – Assigns a string name to a binding for keyed resolution. +- **@instance** – Marks a method or class so that a new instance is provided on each request. +- **@provide** – Marks a method whose return value should be registered as a provider, supporting DI into its parameters. +- **@named** – Assigns a string name to a binding for keyed resolution and injection. - **@params** – Indicates that a parameter should be injected with runtime-supplied arguments. +- **@injectable** – Marks a class as eligible for automatic field injection. Fields annotated with `@inject` will be injected by the code generator. +- **@inject** – Marks a field to be automatically injected by the code generator. +- **@scope** – Declares the DI scope from which a dependency should be resolved for a field. These annotations streamline DI configuration and serve as markers for code generation tools such as [`cherrypick_generator`](https://pub.dev/packages/cherrypick_generator). @@ -32,18 +35,21 @@ Add as a `dev_dependency` for code generation: ```yaml dev_dependencies: + cherrypick_generator: ^latest build_runner: ^latest - cherrypick_generator: ``` -### 2. Annotate your DI modules and providers +--- + +### 2. Annotate your DI modules, providers, and injectable classes + +#### **Module and Provider Example** ```dart import 'package:cherrypick_annotations/cherrypick_annotations.dart'; -import 'package:cherrypick/cherrypick.dart'; @module() -abstract class AppModule extends Module { +abstract class AppModule { @singleton() Dio dio() => Dio(); @@ -61,7 +67,7 @@ abstract class AppModule extends Module { } ``` -When used with `cherrypick_generator`, code similar to the following will be generated: +With `cherrypick_generator`, code like the following will be generated: ```dart final class $AppModule extends AppModule { @@ -78,13 +84,78 @@ final class $AppModule extends AppModule { --- +#### **Field Injection Example** + +```dart +import 'package:cherrypick_annotations/cherrypick_annotations.dart'; + +@injectable() +class ProfileView with _$ProfileView{ + @inject() + late final AuthService auth; + + @inject() + @scope('profile') + late final ProfileManager manager; + + @inject() + @named('admin') + late final UserService adminUserService; +} +``` + +The code generator produces a mixin (simplified): + +```dart +mixin _$ProfileView { + void _inject(ProfileView instance) { + instance.auth = CherryPick.openRootScope().resolve(); + instance.manager = CherryPick.openScope(scopeName: 'profile').resolve(); + instance.adminUserService = CherryPick.openRootScope().resolve(named: 'admin'); + } +} +``` + +--- + ## Annotation Reference +### `@injectable` + +```dart +@injectable() +class MyWidget { ... } +``` +Marks a class as injectable for CherryPick DI. The code generator will generate a mixin to perform automatic injection of fields marked with `@inject()`. + +--- + +### `@inject` + +```dart +@inject() +late final SomeService service; +``` +Applied to a field to request automatic injection of the dependency using the CherryPick DI framework. + +--- + +### `@scope` + +```dart +@inject() +@scope('profile') +late final ProfileManager manager; +``` +Specifies the scope from which the dependency should be resolved for an injected field. + +--- + ### `@module` ```dart @module() -abstract class AppModule extends Module {} +abstract class AppModule {} ``` Use on classes to mark them as a DI module. This is the root for registering your dependency providers. @@ -126,7 +197,8 @@ Use on methods to indicate they provide a dependency to the DI module. Dependenc @named('token') String token() => 'abc'; ``` -Assigns a name to a binding for keyed injection or resolution. +Assigns a name to a binding for keyed injection or resolution. +Can be used on both provider methods and fields. --- @@ -136,7 +208,7 @@ Assigns a name to a binding for keyed injection or resolution. @provide() String greet(@params() dynamic params) => 'Hello $params'; ``` -Use on method parameters to indicate that this parameter should receive runtime-supplied arguments during dependency resolution (for example, via `.toProvide*((params) => greate(params))` in generated code). +Indicates that this parameter should receive runtime-supplied arguments during dependency resolution. ---