docs(annotations): unify and improve English DartDoc for all DI annotations

- Updated all annotation files with complete English DartDoc, field/class/method usage, practical code samples
- Unified documentation style for @inject, @injectable, @instance, @singleton, @named, @scope, @params, @provide, @module
- Removed Russian comments for clarity and consistency
- Improved discoverability and IDE/autocomplete experience for CherryPick DI users
- No functional or API changes; documentation/dev experience only
This commit is contained in:
Sergey Penkovsky
2025-08-12 16:18:53 +03:00
parent 5710af2f9b
commit 884df50a34
10 changed files with 190 additions and 281 deletions

View File

@@ -12,6 +12,9 @@
# The core lints are also what is used by pub.dev for scoring packages.
include: package:lints/recommended.yaml
analyzer:
errors:
camel_case_types: ignore
# Uncomment the following section to specify additional rules.

View File

@@ -13,22 +13,30 @@
import 'package:meta/meta.dart';
/// Annotation for field injection in CherryPick DI framework.
/// Apply this to a field, and the code generator will automatically inject
/// the appropriate dependency into it.
/// Marks a field for dependency injection by CherryPick's code generator.
///
/// ---
/// Use `@inject()` on fields within a class marked with `@injectable()`.
/// Such fields will be automatically injected from the DI [Scope]
/// when using the generated mixin or calling `.injectFields()`.
///
/// Аннотация для внедрения зависимости в поле через фреймворк CherryPick DI.
/// Поместите её на поле класса — генератор кода автоматически подставит нужную зависимость.
///
/// Example / Пример:
/// Example:
/// ```dart
/// @inject()
/// late final SomeService service;
/// import 'package:cherrypick_annotations/cherrypick_annotations.dart';
///
/// @injectable()
/// class LoginScreen with _\$LoginScreen {
/// @inject()
/// late final AuthService authService;
///
/// @inject()
/// @named('main')
/// late final ApiClient api;
/// }
///
/// // After running build_runner, call:
/// // LoginScreen().injectFields();
/// ```
@experimental
// ignore: camel_case_types
final class inject {
const inject();
}

View File

@@ -13,26 +13,31 @@
import 'package:meta/meta.dart';
/// Marks a class as injectable for the CherryPick dependency injection framework.
/// If a class is annotated with [@injectable()], the code generator will
/// create a mixin to perform automatic injection of fields marked with [@inject].
/// Marks a class as injectable, enabling automatic field injection by CherryPick's code generator.
///
/// ---
/// Use `@injectable()` on a class whose fields (marked with `@inject`) you want to be automatically injected from the DI [Scope].
/// When used together with code generation (see cherrypick_generator), a mixin will be generated to inject fields.
///
/// Помечает класс как внедряемый для фреймворка внедрения зависимостей CherryPick.
/// Если класс помечен аннотацией [@injectable()], генератор создаст миксин
/// для автоматического внедрения полей, отмеченных [@inject].
///
/// Example / Пример:
/// Example:
/// ```dart
/// import 'package:cherrypick_annotations/cherrypick_annotations.dart';
///
/// @injectable()
/// class MyWidget extends StatelessWidget {
/// class ProfileScreen with _\$ProfileScreen {
/// @inject()
/// late final MyService service;
/// late final UserManager manager;
///
/// @inject()
/// @named('main')
/// late final ApiClient api;
/// }
///
/// // After running build_runner, call:
/// // profileScreen.injectFields();
/// ```
///
/// After running the generator, the mixin (`_\$ProfileScreen`) will be available to help auto-inject all [@inject] fields in your widget/service/controller.
@experimental
// ignore: camel_case_types
final class injectable {
const injectable();
}

View File

@@ -11,58 +11,39 @@
// limitations under the License.
//
/// ENGLISH:
/// Annotation to specify that a new instance should be provided on each request.
import 'package:meta/meta.dart';
/// Marks a provider method or class to always create a new instance (factory) in CherryPick DI.
///
/// Use the `@instance()` annotation for methods or classes in your DI module
/// to declare that the DI container must create a new object every time
/// the dependency is injected (i.e., no singleton behavior).
/// Use `@instance()` to annotate methods or classes in your DI module/class
/// when you want a new object to be created on every injection (no singleton caching).
/// The default DI lifecycle is instance/factory unless otherwise specified.
///
/// Example:
/// ### Example (in a module method)
/// ```dart
/// import 'package:cherrypick_annotations/cherrypick_annotations.dart';
///
/// @module()
/// abstract class AppModule extends Module {
/// abstract class FeatureModule {
/// @instance()
/// Foo foo() => Foo();
/// MyService provideService() => MyService();
///
/// @singleton()
/// Logger provideLogger() => Logger();
/// }
/// ```
///
/// This will generate:
/// ### Example (on a class, with @injectable)
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// bind<Foo>().toInstance(() => foo());
/// }
/// @injectable()
/// @instance()
/// class MyFactoryClass {
/// // ...
/// }
/// ```
///
/// RUSSIAN (Русский):
/// Аннотация для создания нового экземпляра при каждом запросе.
///
/// Используйте `@instance()` для методов или классов в DI-модуле,
/// чтобы указать, что контейнер внедрения зависимостей должен создавать
/// новый объект при каждом обращении к зависимости (то есть, не синглтон).
///
/// Пример:
/// ```dart
/// @module()
/// abstract class AppModule extends Module {
/// @instance()
/// Foo foo() => Foo();
/// }
/// ```
///
/// Будет сгенерирован следующий код:
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// bind<Foo>().toInstance(() => foo());
/// }
/// }
/// ```
// ignore: camel_case_types
/// See also: [@singleton]
@experimental
final class instance {
const instance();
}

View File

@@ -11,59 +11,40 @@
// limitations under the License.
//
/// ENGLISH:
/// Annotation for marking Dart classes or libraries as modules.
import 'package:meta/meta.dart';
/// Marks an abstract Dart class as a dependency injection module for CherryPick code generation.
///
/// Use the `@module()` annotation on abstract classes (or on a library)
/// to indicate that the class represents a DI (Dependency Injection) module.
/// This is commonly used in code generation tools to automatically register
/// and configure dependencies defined within the module.
/// Use `@module()` on your abstract class to indicate it provides DI bindings (via provider methods).
/// This enables code generation of a concrete module that registers all bindings from your methods.
///
/// Example:
/// Typical usage:
/// ```dart
/// import 'package:cherrypick_annotations/cherrypick_annotations.dart';
///
/// @module()
/// abstract class AppModule extends Module {
/// // Dependency definitions go here.
/// abstract class AppModule {
/// @singleton()
/// Logger provideLogger() => Logger();
///
/// @named('mock')
/// ApiClient mockApi() => MockApiClient();
/// }
/// ```
///
/// Generates code like:
/// The generated code will look like:
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// // Dependency registration...
/// // Dependency registration code...
/// }
/// }
/// ```
///
/// RUSSIAN (Русский):
/// Аннотация для пометки классов или библиотек Dart как модуля.
///
/// Используйте `@module()` для абстрактных классов (или библиотек), чтобы
/// показать, что класс реализует DI-модуль (Dependency Injection).
/// Обычно используется генераторами кода для автоматической регистрации
/// и конфигурирования зависимостей, определённых в модуле.
///
/// Пример:
/// ```dart
/// @module()
/// abstract class AppModule extends Module {
/// // Определения зависимостей
/// }
/// ```
///
/// Будет сгенерирован код:
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// // Регистрация зависимостей...
/// }
/// }
/// ```
// ignore: camel_case_types
/// See also: [@provide], [@singleton], [@instance], [@named]
@experimental
final class module {
/// Creates a [module] annotation.
/// Creates a [module] annotation for use on a DI module class.
const module();
}

View File

@@ -11,67 +11,52 @@
// limitations under the License.
//
/// ENGLISH:
/// Annotation to assign a name or identifier to a class, method, or other element.
import 'package:meta/meta.dart';
/// Assigns a name or key identifier to a class, field, factory method or parameter
/// for use in multi-registration scenarios (named dependencies) in CherryPick DI.
///
/// The `@named('value')` annotation allows you to specify a string name
/// for a dependency, factory, or injectable. This is useful for distinguishing
/// between multiple registrations of the same type in dependency injection,
/// code generation, and for providing human-readable metadata.
/// Use `@named('key')` to distinguish between multiple bindings/implementations
/// of the same type—when registering and when injecting dependencies.
///
/// Example:
/// You can use `@named`:
/// - On provider/factory methods in a module
/// - On fields with `@inject()` to receive a named instance
/// - On function parameters (for method/constructor injection)
///
/// ### Example: On Provider Method
/// ```dart
/// @module()
/// abstract class AppModule extends Module {
/// @named('dio')
/// Dio dio() => Dio();
/// abstract class AppModule {
/// @named('main')
/// ApiClient apiClient() => ApiClient();
///
/// @named('mock')
/// ApiClient mockApi() => MockApiClient();
/// }
/// ```
///
/// This will generate:
/// ### Example: On Injectable Field
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// bind<Dio>().toProvide(() => dio()).withName('dio').singleton();
/// }
/// @injectable()
/// class WidgetModel with _\$WidgetModel {
/// @inject()
/// @named('main')
/// late final ApiClient api;
/// }
/// ```
///
/// RUSSIAN (Русский):
/// Аннотация для задания имени или идентификатора классу, методу или другому элементу.
///
/// Аннотация `@named('значение')` позволяет указать строковое имя для зависимости,
/// фабрики или внедряемого значения. Это удобно для различения нескольких
/// регистраций одного типа в DI, генерации кода.
///
/// Пример:
/// ### Example: On Parameter
/// ```dart
/// @module()
/// abstract class AppModule extends Module {
/// @named('dio')
/// Dio dio() => Dio();
/// class UserScreen {
/// UserScreen(@named('current') User user);
/// }
/// ```
///
/// Будет сгенерирован следующий код:
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// bind<Dio>().toProvide(() => dio()).withName('dio').singleton();
/// }
/// }
/// ```
// ignore: camel_case_types
@experimental
final class named {
/// EN: The assigned name or identifier for the element.
///
/// RU: Назначенное имя или идентификатор для элемента.
/// The assigned name or identifier for the dependency, provider, or parameter.
final String value;
/// EN: Creates a [named] annotation with the given [value].
///
/// RU: Создаёт аннотацию [named] с заданным значением [value].
/// Creates a [named] annotation with the given [value] key or name.
const named(this.value);
}

View File

@@ -11,46 +11,33 @@
// limitations under the License.
//
/// ENGLISH:
/// Annotation to mark a method parameter for injection with run-time arguments.
import 'package:meta/meta.dart';
/// Marks a parameter in a provider method to receive dynamic runtime arguments when resolving a dependency.
///
/// Use the `@params()` annotation to specify that a particular parameter of a
/// provider method should be assigned a value supplied at resolution time,
/// rather than during static dependency graph creation. This is useful in DI
/// when a dependency must receive dynamic data passed by the consumer
/// (via `.withParams(...)` in the generated code).
/// Use `@params()` in a DI module/factory method when the value must be supplied by the user/code at injection time,
/// not during static wiring (such as user input, navigation arguments, etc).
///
/// This enables CherryPick and its codegen to generate .withParams or .toProvideWithParams bindings — so your provider can access runtime values.
///
/// Example:
/// ```dart
/// @provide()
/// String greet(@params() dynamic params) => 'Hello $params';
/// ```
/// import 'package:cherrypick_annotations/cherrypick_annotations.dart';
///
/// This will generate:
/// @module()
/// abstract class FeatureModule {
/// @provide
/// UserManager createManager(@params Map<String, dynamic> runtimeParams) {
/// return UserManager.forUserId(runtimeParams['userId']);
/// }
/// }
/// ```
/// Usage at injection/resolution:
/// ```dart
/// bind<String>().toProvideWithParams((args) => greet(args));
/// final manager = scope.resolve<UserManager>(params: {'userId': myId});
/// ```
///
/// RUSSIAN (Русский):
/// Аннотация для пометки параметра метода, который будет внедряться со значением во время выполнения.
///
/// Используйте `@params()` чтобы указать, что конкретный параметр метода-провайдера
/// должен получать значение, передаваемое в момент обращения к зависимости,
/// а не на этапе построения графа зависимостей. Это полезно, если зависимость
/// должна получать данные динамически от пользователя или другого процесса
/// через `.withParams(...)` в сгенерированном коде.
///
/// Пример:
/// ```dart
/// @provide()
/// String greet(@params() dynamic params) => 'Hello $params';
/// ```
///
/// Будет сгенерировано:
/// ```dart
/// bind<String>().toProvideWithParams((args) => greet(args));
/// ```
// ignore: camel_case_types
@experimental
final class params {
/// Marks a method/constructor parameter as supplied at runtime by the caller.
const params();
}

View File

@@ -11,60 +11,34 @@
// limitations under the License.
//
/// ENGLISH:
/// Annotation to declare a factory/provider method or class as a singleton.
import 'package:meta/meta.dart';
/// Marks a method or class as a dependency provider (factory/provider) for CherryPick module code generation.
///
/// Use the `@singleton()` annotation on methods in your DI module to specify
/// that only one instance of the resulting object should be created and shared
/// for all consumers. This is especially useful in dependency injection
/// frameworks and service locators.
/// Use `@provide` on any method inside a `@module()` annotated class when you want that method
/// to be used as a DI factory/provider during code generation.
///
/// This should be used for methods that create dynamic, optional, or complex dependencies, especially
/// if you want to control the codegen/injection pipeline explicitly and support parameters.
///
/// Example:
/// ```dart
/// import 'package:cherrypick_annotations/cherrypick_annotations.dart';
///
/// @module()
/// abstract class AppModule extends Module {
/// abstract class FeatureModule {
/// @provide
/// Future<Api> provideApi(@params Map<String, dynamic> args) async => ...;
///
/// @singleton()
/// Dio dio() => Dio();
/// @provide
/// Logger provideLogger() => Logger();
/// }
/// ```
///
/// This generates the following code:
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// bind<Dio>().toProvide(() => dio()).singleton();
/// }
/// }
/// ```
///
/// RUSSIAN (Русский):
/// Аннотация для объявления фабричного/провайдерного метода или класса синглтоном.
///
/// Используйте `@singleton()` для методов внутри DI-модуля, чтобы указать,
/// что соответствующий объект (экземпляр класса) должен быть создан только один раз
/// и использоваться всеми компонентами приложения (единый общий экземпляр).
/// Это характерно для систем внедрения зависимостей и сервис-локаторов.
///
/// Пример:
/// ```dart
/// @module()
/// abstract class AppModule extends Module {
/// @singleton()
/// Dio dio() => Dio();
/// }
/// ```
///
/// Будет сгенерирован следующий код:
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// bind<Dio>().toProvide(() => dio()).singleton();
/// }
/// }
/// ```
// ignore: camel_case_types
/// See also: [@singleton], [@instance], [@params], [@named]
@experimental
final class provide {
/// Creates a [provide] annotation.
const provide();
}

View File

@@ -13,25 +13,41 @@
import 'package:meta/meta.dart';
/// Annotation to specify a scope for dependency injection in CherryPick.
/// Use this on an injected field to indicate from which scope
/// the dependency must be resolved.
/// Specifies the DI scope or region from which a dependency should be resolved.
///
/// ---
/// Use `@scope('scopeName')` on an injected field, parameter, or provider method when you want
/// to resolve a dependency not from the current scope, but from another named scope/subcontainer.
///
/// Аннотация для указания области внедрения (scope) в CherryPick.
/// Используйте её на инъецируемом поле, чтобы определить из какой области
/// должна быть получена зависимость.
/// Useful for advanced DI scenarios: multi-feature/state isolation, navigation stacks, explicit subscopes, or testing.
///
/// Example / Пример:
/// Example (injected field):
/// ```dart
/// @inject()
/// @scope('profile')
/// late final ProfileManager profileManager;
/// @injectable()
/// class ProfileScreen with _\$ProfileScreen {
/// @inject()
/// @scope('profile')
/// late final ProfileManager manager;
/// }
/// ```
///
/// Example (parameter):
/// ```dart
/// class TabBarModel {
/// TabBarModel(@scope('tabs') TabContext context);
/// }
/// ```
///
/// Example (in a module):
/// ```dart
/// @module()
/// abstract class FeatureModule {
/// @provide
/// Service service(@scope('shared') SharedConfig config);
/// }
/// ```
@experimental
// ignore: camel_case_types
final class scope {
/// The name/key of the DI scope from which to resolve this dependency.
final String? name;
const scope(this.name);
}

View File

@@ -11,63 +11,32 @@
// limitations under the License.
//
/// ENGLISH:
/// Annotation to declare a dependency as a singleton.
import 'package:meta/meta.dart';
/// Marks a provider method or class so its instance is created only once and shared (singleton) for DI in CherryPick.
///
/// Use the `@singleton()` annotation on provider methods inside a module
/// to indicate that only a single instance of this dependency should be
/// created and shared throughout the application's lifecycle. This is
/// typically used in dependency injection frameworks or service locators
/// to guarantee a single shared instance.
/// Use `@singleton()` on provider methods or classes in your DI module to ensure only one instance is ever created
/// and reused across the application's lifetime (or scope lifetime).
///
/// Example:
/// ```dart
/// import 'package:cherrypick_annotations/cherrypick_annotations.dart';
///
/// @module()
/// abstract class AppModule extends Module {
/// abstract class AppModule {
/// @singleton()
/// Dio dio() => Dio();
/// ApiClient createApi() => ApiClient();
/// }
/// ```
///
/// This will generate code like:
/// The generated code will ensure:
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// bind<Dio>().toProvide(() => dio()).singleton();
/// }
/// }
/// bind<ApiClient>().toProvide(() => createApi()).singleton();
/// ```
///
/// RUSSIAN (Русский):
/// Аннотация для объявления зависимости как синглтона.
///
/// Используйте `@singleton()` для методов-провайдеров внутри модуля,
/// чтобы указать, что соответствующий объект должен быть создан
/// единожды и использоваться во всём приложении (общий синглтон).
/// Это характерно для систем внедрения зависимостей и сервис-локаторов,
/// чтобы гарантировать один общий экземпляр.
///
/// Пример:
/// ```dart
/// @module()
/// abstract class AppModule extends Module {
/// @singleton()
/// Dio dio() => Dio();
/// }
/// ```
///
/// Будет сгенерирован следующий код:
/// ```dart
/// final class $AppModule extends AppModule {
/// @override
/// void builder(Scope currentScope) {
/// bind<Dio>().toProvide(() => dio()).singleton();
/// }
/// }
/// ```
// ignore: camel_case_types
/// See also: [@instance], [@provide], [@named]
@experimental
final class singleton {
/// Creates a [singleton] annotation.
/// Creates a [singleton] annotation for DI providers/classes.
const singleton();
}