From 9fee26c524facad23f6d633501de65a9ccb7d827 Mon Sep 17 00:00:00 2001 From: Sergey Penkovsky Date: Thu, 14 Aug 2025 15:46:53 +0300 Subject: [PATCH] feat(i18n): add initial Russian localization for documentation and site config - Added full Russian translations for all main documentation sections () into . - Sections translated include: key features, installation, getting started, all core concepts, advanced features, API reference, FAQ, links, additional modules, contributing, and license. - Updated to ensure language switching is available and Russian locale is active. - Each Russian file preserves the structure and formatting of the original Markdown, with machine-aided draft translation for immediate use. - Lays the groundwork for UI language switching (en/ru) and enables further manual translation refinement and review. --- website/docusaurus.config.ts | 12 +- .../current/additional-modules.md | 14 ++ .../circular-dependency-detection.md | 71 ++++++++++ .../hierarchical-subscopes.md | 45 +++++++ .../current/advanced-features/logging.md | 62 +++++++++ .../performance-improvements.md | 10 ++ .../current/contributing.md | 7 + .../current/core-concepts/binding.md | 41 ++++++ .../current/core-concepts/disposable.md | 52 ++++++++ .../current/core-concepts/module.md | 19 +++ .../current/core-concepts/scope.md | 31 +++++ .../current/dependency-resolution-api.md | 15 +++ .../current/documentation-links.md | 7 + .../current/example-application.md | 124 ++++++++++++++++++ .../current/faq.md | 10 ++ .../current/getting-started.md | 27 ++++ .../current/installation.md | 18 +++ .../current/key-features.md | 16 +++ .../current/license.md | 9 ++ .../current/using-annotations.md | 102 ++++++++++++++ 20 files changed, 682 insertions(+), 10 deletions(-) create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/additional-modules.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/circular-dependency-detection.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/hierarchical-subscopes.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/logging.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/performance-improvements.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/contributing.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/binding.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/disposable.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/module.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/scope.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/dependency-resolution-api.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/documentation-links.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/example-application.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/faq.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/getting-started.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/installation.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/key-features.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/license.md create mode 100644 website/i18n/ru/docusaurus-plugin-content-docs/current/using-annotations.md diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index a2a79c0..b401852 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -112,16 +112,8 @@ const config: Config = { title: 'Community', items: [ { - label: 'Stack Overflow', - href: 'https://stackoverflow.com/questions/tagged/docusaurus', - }, - { - label: 'Discord', - href: 'https://discordapp.com/invite/docusaurus', - }, - { - label: 'X', - href: 'https://x.com/docusaurus', + label: 'Telegram', + href: 'https://t.me/+22IVT0vqXBg1NDdi', }, ], }, diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/additional-modules.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/additional-modules.md new file mode 100644 index 0000000..1a8bec9 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/additional-modules.md @@ -0,0 +1,14 @@ +--- +sidebar_position: 9 +--- + +# Дополнительные модули + +CherryPick предоставляет набор официальных доп. модулей для расширенных и специфичных сценариев: + +| Имя модуля | Описание | +|--------------------------|--------------------------------------------------------------| +| [**cherrypick_annotations**](https://pub.dev/packages/cherrypick_annotations) | Dart-аннотации для лаконичного DI и генерации кода. | +| [**cherrypick_generator**](https://pub.dev/packages/cherrypick_generator) | Генератор кода для автосборки DI-привязок по аннотациям. | +| [**cherrypick_flutter**](https://pub.dev/packages/cherrypick_flutter) | Интеграция DI с Flutter: виджеты-провайдеры, injection. | +| [**talker_cherrypick_logger**](https://pub.dev/packages/talker_cherrypick_logger) | Продвинутый логгер событий DI CherryPick с интеграцией в [Talker](https://pub.dev/packages/talker). Позволяет визуализировать состояние, ошибки и автоматически отслеживать DI прямо в UI и консоли. | diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/circular-dependency-detection.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/circular-dependency-detection.md new file mode 100644 index 0000000..37f8e60 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/circular-dependency-detection.md @@ -0,0 +1,71 @@ +--- +sidebar_position: 3 +--- + +# Обнаружение циклических зависимостей + +CherryPick может обнаруживать циклические зависимости в вашей DI-конфигурации, помогая избежать бесконечных циклов и сложных для отладки ошибок. + +## Как использовать: + +### 1. Включите обнаружение во время разработки + +**Локально (в рамках одного скоупа):** +```dart +final scope = CherryPick.openSafeRootScope(); // Локальное обнаружение включено по умолчанию +// или для существующего скоупа: +scope.enableCycleDetection(); +``` + +**Глобально (между скоупами):** +```dart +CherryPick.enableGlobalCrossScopeCycleDetection(); +final rootScope = CherryPick.openGlobalSafeRootScope(); +``` + +### 2. Пример ошибки + +Если вы объявите взаимозависимые сервисы: +```dart +class A { A(B b); } +class B { B(A a); } + +scope.installModules([ + Module((bind) { + bind().to((s) => A(s.resolve())); + bind().to((s) => B(s.resolve())); + }), +]); + +scope.resolve(); // выбросит CircularDependencyException +``` + +### 3. Общая рекомендация + +- **Включайте обнаружение** всегда в debug и тестовой среде для максимальной безопасности. +- **Отключайте обнаружение** в production после завершения тестирования, ради производительности. + +```dart +import 'package:flutter/foundation.dart'; + +void main() { + if (kDebugMode) { + CherryPick.enableGlobalCycleDetection(); + CherryPick.enableGlobalCrossScopeCycleDetection(); + } + runApp(MyApp()); +} +``` + +### 4. Отладка и обработка ошибок + +При обнаружении будет выброшено исключение `CircularDependencyException` с цепочкой зависимостей: +```dart +try { + scope.resolve(); +} on CircularDependencyException catch (e) { + print('Цепочка зависимостей: ${e.dependencyChain}'); +} +``` + +**Подробнее:** смотрите [cycle_detection.ru.md](doc/cycle_detection.ru.md) diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/hierarchical-subscopes.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/hierarchical-subscopes.md new file mode 100644 index 0000000..dde7e38 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/hierarchical-subscopes.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 1 +--- + +# Иерархические подскоупы + +CherryPick поддерживает иерархическую структуру скоупов, что позволяет строить сложные и модульные графы зависимостей для профессиональных архитектур приложений. Каждый подскоуп наследует зависимости родителя и позволяет переопределять их локально. + +## Основные моменты + +- **Подскоупы** — дочерние скоупы, открываемые от любого существующего (в том числе root). +- Зависимости подскоупа перекрывают родительские при разрешении. +- Если зависимость не найдена в подскоупе, CherryPick ищет её выше по иерархии. +- Подскоупы могут иметь собственные модули, "жизненный цикл", Disposable-объекты. +- Можно делать вложенность любой глубины для фич, компонентов и т.д. + +## Пример + +```dart +final rootScope = CherryPick.openRootScope(); +rootScope.installModules([AppModule()]); + +// Открыть подскоуп для функции/страницы +final userFeatureScope = rootScope.openSubScope('userFeature'); +userFeatureScope.installModules([UserFeatureModule()]); + +// В userFeatureScope сперва ищет в своей области +final userService = userFeatureScope.resolve(); + +// Если не нашлось — идёт в rootScope +final sharedService = userFeatureScope.resolve(); + +// Подскоупы можно вкладывать друг в друга сколь угодно глубоко +final dialogScope = userFeatureScope.openSubScope('dialog'); +dialogScope.installModules([DialogModule()]); +final dialogManager = dialogScope.resolve(); +``` + +## Применение + +- Модульная изоляция частей/экранов с собственными зависимостями +- Переопределение сервисов для конкретных сценариев/навигации +- Управление жизнью и освобождением ресурсов по группам + +**Совет:** Всегда закрывайте подскоупы, когда они больше не нужны, чтобы освободить ресурсы. diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/logging.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/logging.md new file mode 100644 index 0000000..979f8cd --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/logging.md @@ -0,0 +1,62 @@ +--- +sidebar_position: 2 +--- + +# Логирование + +CherryPick позволяет логировать все события и ошибки DI с помощью расширяемого observer-механизма. + +## Кастомные Observer'ы + +Вы можете передавать свою реализацию `CherryPickObserver` в root- или любой подскоуп. +Это позволяет централизовать и настраивать логирование, направлять логи в консоль, файл, сторонние сервисы или системы как [Talker](https://pub.dev/packages/talker). + +### Пример: вывод всех событий в консоль + +```dart +import 'package:cherrypick/cherrypick.dart'; + +void main() { + // Встроенный PrintCherryPickObserver для консоли + final observer = PrintCherryPickObserver(); + final scope = CherryPick.openRootScope(observer: observer); + // Все события и ошибки DI будут выведены! +} +``` + +### Пример: расширенное логирование через Talker + +Для более гибкого логирования или UI-оверлеев можно использовать observer наподобие [talker_cherrypick_logger](../talker_cherrypick_logger): + +```dart +import 'package:cherrypick/cherrypick.dart'; +import 'package:talker/talker.dart'; +import 'package:talker_cherrypick_logger/talker_cherrypick_logger.dart'; + +void main() { + final talker = Talker(); + final observer = TalkerCherryPickObserver(talker); + CherryPick.openRootScope(observer: observer); + // Все события попадают в Talker! +} +``` + +## Поведение по умолчанию +- По умолчанию логирование "тихое" (SilentCherryPickObserver) для production — нет вывода без observer'а. +- Можно назначить observer для любого скоупа. + +## Возможности Observer'а + +- Регистрация зависимостей +- Получение/создание/удаление экземпляров +- Установка/удаление модулей +- Открытие/закрытие скоупов +- Кэш-хиты/мимо +- Обнаружение циклов +- Диагностика, предупреждения, ошибки + +## Когда применять + +- Подробное логирование в dev/test окружениях +- Передача логов в основную систему/аналитику +- Отладка и профилирование DI diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/performance-improvements.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/performance-improvements.md new file mode 100644 index 0000000..0d5fa97 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/advanced-features/performance-improvements.md @@ -0,0 +1,10 @@ +--- +sidebar_position: 4 +--- + +# Улучшения производительности + +> **Примечание по производительности:** +> **Начиная с версии 3.0.0**, CherryPick использует Map-индексатор для поиска зависимостей. Это означает, что вызовы `resolve()` и связанные методы работают за O(1) независимо от количества модулей/биндингов в скоупе. Ранее библиотека просматривала все модули/биндинги, что могло замедлять DI в крупных проектах. +> +> Эта оптимизация полностью внутренняя: интерфейс библиотеки и пользовательский код не изменились, но производительность заметно выросла на больших графах зависимостей. diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/contributing.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/contributing.md new file mode 100644 index 0000000..7762cc1 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/contributing.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 10 +--- + +# Вклад в проект + +Вкладывайтесь! Открывайте задачи или отправляйте pull request'ы на [GitHub](https://github.com/pese-git/cherrypick). diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/binding.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/binding.md new file mode 100644 index 0000000..23ed1dd --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/binding.md @@ -0,0 +1,41 @@ +--- +sidebar_position: 1 +--- + +# Привязка (Binding) + +**Binding** — это конфигурация, которая определяет, как создавать или предоставлять конкретную зависимость. Binding поддерживает: + +* Прямое присваивание экземпляра (`toInstance()`, `toInstanceAsync()`) +* Ленивые провайдеры (синхронные/асинхронные функции) +* Провайдеры с поддержкой динамических параметров +* Именованные экземпляры для получения по строковому ключу +* Необязательное управление жизненным циклом синглтона + +## Пример + +```dart +// Прямое создание экземпляра +Binding().toInstance("Hello world"); + +// Асинхронное создание экземпляра +Binding().toInstanceAsync(Future.value("Hello world")); + +// Ленивое создание экземпляра через фабрику (sync) +Binding().toProvide(() => "Hello world"); + +// Ленивое создание экземпляра через фабрику (async) +Binding().toProvideAsync(() async => "Hello async world"); + +// Экземпляр с параметрами (sync) +Binding().toProvideWithParams((params) => "Hello $params"); + +// Экземпляр с параметрами (async) +Binding().toProvideAsyncWithParams((params) async => "Hello $params"); + +// Именованный экземпляр для получения по имени +Binding().toProvide(() => "Hello world").withName("my_string"); + +// Синглтон (один экземпляр внутри скоупа) +Binding().toProvide(() => "Hello world").singleton(); +``` diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/disposable.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/disposable.md new file mode 100644 index 0000000..c08b582 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/disposable.md @@ -0,0 +1,52 @@ +--- +sidebar_position: 4 +--- + +# Disposable + +CherryPick может автоматически очищать любые зависимости, реализующие интерфейс `Disposable`. Это упрощает управление ресурсами (контроллеры, потоки, сокеты, файлы и др.) — особенно при закрытии скоупа или приложения. + +Если вы регистрируете объект, реализующий `Disposable`, как синглтон или через DI-контейнер, CherryPick вызовет его метод `dispose()` при закрытии или очистке скоупа. + +## Основные моменты +- Поддерживаются синхронная и асинхронная очистка (dispose может возвращать `void` или `Future`). +- Все объекты `Disposable` из текущего скоупа и подскоупов будут удалены в правильном порядке. +- Предотвращает утечки ресурсов и обеспечивает корректную очистку. +- Не нужно вручную связывать очистку — просто реализуйте интерфейс. + +## Минимальный синхронный пример +```dart +class CacheManager implements Disposable { + void dispose() { + cache.clear(); + print('CacheManager удалён!'); + } +} + +final scope = CherryPick.openRootScope(); +scope.installModules([ + Module((bind) => bind().toProvide(() => CacheManager()).singleton()), +]); + +// ...спустя время +await CherryPick.closeRootScope(); // выведет: CacheManager удалён! +``` + +## Асинхронный пример +```dart +class MyServiceWithSocket implements Disposable { + @override + Future dispose() async { + await socket.close(); + print('Socket закрыт!'); + } +} + +scope.installModules([ + Module((bind) => bind().toProvide(() => MyServiceWithSocket()).singleton()), +]); + +await CherryPick.closeRootScope(); // дождётся завершения async очистки +``` + +**Совет:** Всегда вызывайте `await CherryPick.closeRootScope()` или `await scope.closeSubScope(key)` в вашем shutdown/teardown-коде для гарантированной очистки ресурсов. diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/module.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/module.md new file mode 100644 index 0000000..b185c83 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/module.md @@ -0,0 +1,19 @@ +--- +sidebar_position: 2 +--- + +# Модуль + +**Модуль** — это логическая точка сбора для привязок (bindings), предназначенная для группирования и инициализации связанных зависимостей. Реализуйте метод `builder`, чтобы определить, как зависимости будут связываться внутри скоупа. + +## Пример + +```dart +class AppModule extends Module { + @override + void builder(Scope currentScope) { + bind().toInstance(ApiClientMock()); + bind().toProvide(() => "Hello world!"); + } +} +``` diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/scope.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/scope.md new file mode 100644 index 0000000..43e58a9 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/core-concepts/scope.md @@ -0,0 +1,31 @@ +--- +sidebar_position: 3 +--- + +# Скоуп (Scope) + +**Scope** управляет деревом модулей и экземпляров зависимостей. Скоупы могут быть вложенными (иерархия родитель-дочерний), обеспечивая модульную компоновку приложения и возможность переопределения зависимостей для отдельных контекстов. + +Обычно вы работаете с корневым скоупом, но при необходимости можете создавать именованные подскоупы. + +## Пример + +```dart +// Открыть основной/корневой скоуп +final rootScope = CherryPick.openRootScope(); + +// Установить пользовательский модуль +rootScope.installModules([AppModule()]); + +// Получить зависимость синхронно +final str = rootScope.resolve(); + +// Получить зависимость асинхронно +final result = await rootScope.resolveAsync(); + +// Рекомендуется: закрывать корневой скоуп и высвобождать все ресурсы +await CherryPick.closeRootScope(); + +// Либо вручную вызвать dispose на любом скоупе, которым вы управляете индивидуально +// await rootScope.dispose(); +``` diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/dependency-resolution-api.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/dependency-resolution-api.md new file mode 100644 index 0000000..01ae4c5 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/dependency-resolution-api.md @@ -0,0 +1,15 @@ +--- +sidebar_position: 4 +--- + +# API разрешения зависимостей + +- `resolve()` — получает экземпляр зависимости или выбрасывает исключение, если не найдено. +- `resolveAsync()` — асинхронный вариант для зависимостей с асинхронной инициализацией. +- `tryResolve()` — возвращает `null`, если не найдено (синхронно). +- `tryResolveAsync()` — возвращает `null` асинхронно, если не найдено. + +Поддерживает: +- Синхронные и асинхронные зависимости +- Именованные зависимости +- Провайдеры с runtime-параметрами или без них diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/documentation-links.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/documentation-links.md new file mode 100644 index 0000000..aa6512d --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/documentation-links.md @@ -0,0 +1,7 @@ +--- +sidebar_position: 8 +--- + +# Ссылки на документацию + +* Обнаружение циклических зависимостей [(En)](doc/cycle_detection.en.md)[(Ru)](doc/cycle_detection.ru.md) diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/example-application.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/example-application.md new file mode 100644 index 0000000..b5bb5cc --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/example-application.md @@ -0,0 +1,124 @@ +--- +sidebar_position: 6 +--- + +# Пример приложения + +Ниже приведён полный пример с модулями, подскоупами, асинхронными провайдерами и разрешением зависимостей. + +```dart +import 'dart:async'; +import 'package:meta/meta.dart'; +import 'package:cherrypick/cherrypick.dart'; + +class AppModule extends Module { + @override + void builder(Scope currentScope) { + bind().withName("apiClientMock").toInstance(ApiClientMock()); + bind().withName("apiClientImpl").toInstance(ApiClientImpl()); + } +} + +class FeatureModule extends Module { + final bool isMock; + FeatureModule({required this.isMock}); + @override + void builder(Scope currentScope) { + // Асинхронный провайдер DataRepository с выбором зависимости по имени + bind() + .withName("networkRepo") + .toProvideAsync(() async { + final client = await Future.delayed( + Duration(milliseconds: 100), + () => currentScope.resolve( + named: isMock ? "apiClientMock" : "apiClientImpl", + ), + ); + return NetworkDataRepository(client); + }) + .singleton(); + + // Вызов асинхронного провайдера для DataBloc + bind().toProvideAsync( + () async { + final repo = await currentScope.resolveAsync( + named: "networkRepo"); + return DataBloc(repo); + }, + ); + } +} + +void main() async { + final scope = CherryPick.openRootScope().installModules([AppModule()]); + final featureScope = scope.openSubScope("featureScope") + ..installModules([FeatureModule(isMock: true)]); + + final dataBloc = await featureScope.resolveAsync(); + dataBloc.data.listen( + (d) => print('Получены данные: $d'), + onError: (e) => print('Ошибка: $e'), + onDone: () => print('DONE'), + ); + + await dataBloc.fetchData(); +} + +class DataBloc { + final DataRepository _dataRepository; + Stream get data => _dataController.stream; + final StreamController _dataController = StreamController.broadcast(); + + DataBloc(this._dataRepository); + + Future fetchData() async { + try { + _dataController.sink.add(await _dataRepository.getData()); + } catch (e) { + _dataController.sink.addError(e); + } + } + + void dispose() { + _dataController.close(); + } +} + +abstract class DataRepository { + Future getData(); +} + +class NetworkDataRepository implements DataRepository { + final ApiClient _apiClient; + final _token = 'token'; + NetworkDataRepository(this._apiClient); + + @override + Future getData() async => + await _apiClient.sendRequest( + url: 'www.google.com', + token: _token, + requestBody: {'type': 'data'}, + ); +} + +abstract class ApiClient { + Future sendRequest({@required String? url, String? token, Map? requestBody}); +} + +class ApiClientMock implements ApiClient { + @override + Future sendRequest( + {@required String? url, String? token, Map? requestBody}) async { + return 'Local Data'; + } +} + +class ApiClientImpl implements ApiClient { + @override + Future sendRequest( + {@required String? url, String? token, Map? requestBody}) async { + return 'Network data'; + } +} +``` diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/faq.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/faq.md new file mode 100644 index 0000000..3c30a31 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/faq.md @@ -0,0 +1,10 @@ +--- +sidebar_position: 7 +--- + +# Часто задаваемые вопросы + +### В: Нужно ли использовать `await` с CherryPick.closeRootScope(), CherryPick.closeScope() или scope.dispose(), если у меня нет Disposable-сервисов? + +**О:** +Да! Даже если ваши сервисы сейчас не реализуют `Disposable`, всегда используйте `await` при закрытии скоупов. Если вы позже добавите очистку ресурсов (реализовав dispose()), CherryPick всё обработает автоматически и ваш код останется без изменений. Это гарантирует надежное освобождение ресурсов для любого сценария. diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/getting-started.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/getting-started.md new file mode 100644 index 0000000..a082e43 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/getting-started.md @@ -0,0 +1,27 @@ +--- +sidebar_position: 3 +--- + +# Быстрый старт + +Минимальный пример регистрации и получения зависимости: + +```dart +import 'package:cherrypick/cherrypick.dart'; + +class AppModule extends Module { + @override + void builder(Scope currentScope) { + bind().toInstance(ApiClientMock()); + bind().toProvide(() => "Hello, CherryPick!"); + } +} + +final rootScope = CherryPick.openRootScope(); +rootScope.installModules([AppModule()]); + +final greeting = rootScope.resolve(); +print(greeting); // напечатает: Hello, CherryPick! + +await CherryPick.closeRootScope(); +``` diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/installation.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/installation.md new file mode 100644 index 0000000..2109c0f --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/installation.md @@ -0,0 +1,18 @@ +--- +sidebar_position: 2 +--- + +# Установка + +Добавьте в ваш `pubspec.yaml`: + +```yaml +dependencies: + cherrypick: ^ +``` + +Затем выполните команду: + +```shell +dart pub get +``` diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/key-features.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/key-features.md new file mode 100644 index 0000000..e606b01 --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/key-features.md @@ -0,0 +1,16 @@ +--- +sidebar_position: 1 +--- + +# Ключевые возможности + +- Главный скоуп и именованные подскоупы +- Привязка и разрешение экземпляров по имени +- Асинхронные и синхронные провайдеры +- Провайдеры с поддержкой параметров времени выполнения +- Управление жизненным циклом синглтонов +- Модульная и иерархическая композиция +- Null-safe разрешение зависимостей (tryResolve/tryResolveAsync) +- Обнаружение циклических зависимостей (локально и глобально) +- Подробное логирование состояния и действий DI-контейнера +- Автоматическое освобождение ресурсов для всех зарегистрированных Disposable зависимостей diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/license.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/license.md new file mode 100644 index 0000000..0e9025e --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/license.md @@ -0,0 +1,9 @@ +--- +sidebar_position: 11 +--- + +# Лицензия + +Проект распространяется под [лицензией Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). + +**Важно:** При отсутствии специальных договорённостей поставляется "КАК ЕСТЬ", без каких-либо гарантий. Подробности см. в самой лицензии. diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/using-annotations.md b/website/i18n/ru/docusaurus-plugin-content-docs/current/using-annotations.md new file mode 100644 index 0000000..9ec18ab --- /dev/null +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/using-annotations.md @@ -0,0 +1,102 @@ +--- +sidebar_position: 5 +--- + +# Использование аннотаций и генерация кода + +CherryPick предоставляет продвинутую эргономику и безопасный DI благодаря **аннотациям Dart** и генерации кода. Это позволяет избавить вас от рутины — просто аннотируйте классы, поля и модули, запускайте генератор и используйте полностью автосвязанный DI! + +## Как это работает + +1. **Аннотируйте** сервисы, провайдеры и поля с помощью `cherrypick_annotations`. +2. **Генерируйте** код с помощью `cherrypick_generator` и `build_runner`. +3. **Используйте** автосгенерированные модули и миксины для автоматического внедрения. + +--- + +## Поддерживаемые аннотации + +| Аннотация | Target | Описание | +|---------------------|---------------|--------------------------------------------------------------| +| `@injectable()` | класс | Включает автоподстановку полей (генерируется mixin) | +| `@inject()` | поле | Автоподстановка через DI (работает с @injectable) | +| `@module()` | класс | DI-модуль: методы — провайдеры и сервисы | +| `@provide` | метод | Регистрирует как DI-провайдер (можно с параметрами) | +| `@instance` | метод/класс | Регистрирует новый экземпляр (на каждый resolve, factory) | +| `@singleton` | метод/класс | Регистрация как синглтон (один экземпляр на скоуп) | +| `@named` | поле/параметр | Использование именованных экземпляров для внедрения/resolve | +| `@scope` | поле/параметр | Внедрение/resolve из другого (именованного) скоупа | +| `@params` | параметр | Добавляет user-defined параметры во время resolve | + +--- + +## Пример Field Injection + +```dart +import 'package:cherrypick_annotations/cherrypick_annotations.dart'; + +@injectable() +class ProfilePage with _\$ProfilePage { + @inject() + late final AuthService auth; + + @inject() + @scope('profile') + late final ProfileManager manager; + + @inject() + @named('admin') + late final UserService adminUserService; +} +``` + +- После запуска build_runner миксин `_ProfilePage` будет сгенерирован для внедрения. +- Вызовите `myProfilePage.injectFields();` чтобы все зависимости были внедрены автоматически. + +## Пример модуля/провайдера + +```dart +@module() +abstract class AppModule { + @singleton + AuthService provideAuth(Api api) => AuthService(api); + + @named('logging') + @provide + Future provideLogger(@params Map args) async => ...; +} +``` + +--- + +## Шаги использования + +1. Добавьте зависимости в `pubspec.yaml`. +2. Аннотируйте классы и модули. +3. Генерируйте код командой build_runner. +4. Регистрируйте модули и используйте автосвязь. + +--- + +## Расширенные возможности + +- Используйте `@named` для внедрения по ключу. +- Используйте `@scope` для внедрения из разных скоупов. +- Используйте `@params` для передачи runtime-параметров. + +--- + +## Советы и FAQ + +- После изменений в DI-коде запускайте build_runner заново. +- Не редактируйте `.g.dart` вручную. +- Ошибки некорректных аннотаций определяются автоматически. + +--- + +## Ссылки + +- [Подробнее про аннотации (en)](doc/annotations_en.md) +- [cherrypick_annotations/README.md](../cherrypick_annotations/README.md) +- [cherrypick_generator/README.md](../cherrypick_generator/README.md) +- Полный пример: [`examples/postly`](../examples/postly)