mirror of
https://github.com/pese-git/cherrypick.git
synced 2026-01-23 21:13:35 +00:00
Applied consistent code formatting across all packages using \$ melos format
└> dart format .
└> RUNNING (in 8 packages)
--------------------------------------------------------------------------------
benchmark_di:
Formatted 18 files (0 changed) in 0.30 seconds.
benchmark_di: SUCCESS
--------------------------------------------------------------------------------
cherrypick:
Formatted 24 files (0 changed) in 0.34 seconds.
cherrypick: SUCCESS
--------------------------------------------------------------------------------
cherrypick_annotations:
Formatted 11 files (0 changed) in 0.14 seconds.
cherrypick_annotations: SUCCESS
--------------------------------------------------------------------------------
cherrypick_flutter:
Formatted 3 files (0 changed) in 0.15 seconds.
cherrypick_flutter: SUCCESS
--------------------------------------------------------------------------------
cherrypick_generator:
Formatted 17 files (0 changed) in 0.27 seconds.
cherrypick_generator: SUCCESS
--------------------------------------------------------------------------------
client_app:
Formatted 4 files (0 changed) in 0.14 seconds.
client_app: SUCCESS
--------------------------------------------------------------------------------
postly:
Formatted lib/router/app_router.gr.dart
Formatted 23 files (1 changed) in 0.33 seconds.
postly: SUCCESS
--------------------------------------------------------------------------------
talker_cherrypick_logger:
Formatted 4 files (0 changed) in 0.18 seconds.
talker_cherrypick_logger: SUCCESS
--------------------------------------------------------------------------------
$ melos format
└> dart format .
└> SUCCESS. No functional or logic changes included.
239 lines
7.2 KiB
Dart
239 lines
7.2 KiB
Dart
import 'package:cherrypick/cherrypick.dart';
|
||
|
||
// Пример сервисов для демонстрации
|
||
class DatabaseService {
|
||
void connect() => print('🔌 Connecting to database');
|
||
}
|
||
|
||
class ApiService {
|
||
final DatabaseService database;
|
||
ApiService(this.database);
|
||
|
||
void fetchData() {
|
||
database.connect();
|
||
print('📡 Fetching data via API');
|
||
}
|
||
}
|
||
|
||
class UserService {
|
||
final ApiService apiService;
|
||
UserService(this.apiService);
|
||
|
||
void getUser(String id) {
|
||
apiService.fetchData();
|
||
print('👤 Fetching user: $id');
|
||
}
|
||
}
|
||
|
||
// Модули для различных feature
|
||
class DatabaseModule extends Module {
|
||
@override
|
||
void builder(Scope currentScope) {
|
||
bind<DatabaseService>().singleton().toProvide(() => DatabaseService());
|
||
}
|
||
}
|
||
|
||
class ApiModule extends Module {
|
||
@override
|
||
void builder(Scope currentScope) {
|
||
bind<ApiService>()
|
||
.toProvide(() => ApiService(currentScope.resolve<DatabaseService>()));
|
||
}
|
||
}
|
||
|
||
class UserModule extends Module {
|
||
@override
|
||
void builder(Scope currentScope) {
|
||
bind<UserService>()
|
||
.toProvide(() => UserService(currentScope.resolve<ApiService>()));
|
||
}
|
||
}
|
||
|
||
// Пример циклических зависимостей для демонстрации обнаружения
|
||
class CircularServiceA {
|
||
final CircularServiceB serviceB;
|
||
CircularServiceA(this.serviceB);
|
||
}
|
||
|
||
class CircularServiceB {
|
||
final CircularServiceA serviceA;
|
||
CircularServiceB(this.serviceA);
|
||
}
|
||
|
||
class CircularModuleA extends Module {
|
||
@override
|
||
void builder(Scope currentScope) {
|
||
bind<CircularServiceA>().toProvide(
|
||
() => CircularServiceA(currentScope.resolve<CircularServiceB>()));
|
||
}
|
||
}
|
||
|
||
class CircularModuleB extends Module {
|
||
@override
|
||
void builder(Scope currentScope) {
|
||
bind<CircularServiceB>().toProvide(
|
||
() => CircularServiceB(currentScope.resolve<CircularServiceA>()));
|
||
}
|
||
}
|
||
|
||
void main() {
|
||
print('=== Improved CherryPick Helper Demonstration ===\n');
|
||
|
||
// Example 1: Global enabling of cycle detection
|
||
print('1. Globally enable cycle detection:');
|
||
|
||
CherryPick.enableGlobalCycleDetection();
|
||
print(
|
||
'✅ Global cycle detection enabled: ${CherryPick.isGlobalCycleDetectionEnabled}');
|
||
|
||
// All new scopes will automatically have cycle detection enabled
|
||
final globalScope = CherryPick.openRootScope();
|
||
print(
|
||
'✅ Root scope has cycle detection enabled: ${globalScope.isCycleDetectionEnabled}');
|
||
|
||
// Install modules without circular dependencies
|
||
globalScope.installModules([
|
||
DatabaseModule(),
|
||
ApiModule(),
|
||
UserModule(),
|
||
]);
|
||
|
||
final userService = globalScope.resolve<UserService>();
|
||
userService.getUser('user123');
|
||
print('');
|
||
|
||
// Example 2: Safe scope creation
|
||
print('2. Creating safe scopes:');
|
||
|
||
CherryPick.closeRootScope(); // Закрываем предыдущий скоуп
|
||
CherryPick.disableGlobalCycleDetection(); // Отключаем глобальную настройку
|
||
|
||
// Создаем безопасный скоуп (с автоматически включенным обнаружением)
|
||
final safeScope = CherryPick.openSafeRootScope();
|
||
print(
|
||
'✅ Safe scope created with cycle detection: ${safeScope.isCycleDetectionEnabled}');
|
||
|
||
safeScope.installModules([
|
||
DatabaseModule(),
|
||
ApiModule(),
|
||
UserModule(),
|
||
]);
|
||
|
||
final safeUserService = safeScope.resolve<UserService>();
|
||
safeUserService.getUser('safe_user456');
|
||
print('');
|
||
|
||
// Example 3: Detecting cycles
|
||
print('3. Detecting circular dependencies:');
|
||
|
||
final cyclicScope = CherryPick.openSafeRootScope();
|
||
cyclicScope.installModules([
|
||
CircularModuleA(),
|
||
CircularModuleB(),
|
||
]);
|
||
|
||
try {
|
||
cyclicScope.resolve<CircularServiceA>();
|
||
print('❌ This should not be executed');
|
||
} catch (e) {
|
||
if (e is CircularDependencyException) {
|
||
print('❌ Circular dependency detected!');
|
||
print(' Message: ${e.message}');
|
||
print(' Chain: ${e.dependencyChain.join(' -> ')}');
|
||
}
|
||
}
|
||
print('');
|
||
|
||
// Example 4: Managing detection for specific scopes
|
||
print('4. Managing detection for specific scopes:');
|
||
|
||
CherryPick.closeRootScope();
|
||
|
||
// Создаем скоуп без обнаружения
|
||
// ignore: unused_local_variable
|
||
final specificScope = CherryPick.openRootScope();
|
||
print(
|
||
' Detection in root scope: ${CherryPick.isCycleDetectionEnabledForScope()}');
|
||
|
||
// Включаем обнаружение для конкретного скоупа
|
||
CherryPick.enableCycleDetectionForScope();
|
||
print(
|
||
'✅ Detection enabled for root scope: ${CherryPick.isCycleDetectionEnabledForScope()}');
|
||
|
||
// Создаем дочерний скоуп
|
||
// ignore: unused_local_variable
|
||
final featureScope = CherryPick.openScope(scopeName: 'feature.auth');
|
||
print(
|
||
' Detection in feature.auth scope: ${CherryPick.isCycleDetectionEnabledForScope(scopeName: 'feature.auth')}');
|
||
|
||
// Включаем обнаружение для дочернего скоупа
|
||
CherryPick.enableCycleDetectionForScope(scopeName: 'feature.auth');
|
||
print(
|
||
'✅ Detection enabled for feature.auth scope: ${CherryPick.isCycleDetectionEnabledForScope(scopeName: 'feature.auth')}');
|
||
print('');
|
||
|
||
// Example 5: Creating safe child scopes
|
||
print('5. Creating safe child scopes:');
|
||
|
||
final safeFeatureScope =
|
||
CherryPick.openSafeScope(scopeName: 'feature.payments');
|
||
print(
|
||
'✅ Safe feature scope created: ${safeFeatureScope.isCycleDetectionEnabled}');
|
||
|
||
// You can create a complex hierarchy of scopes
|
||
final complexScope =
|
||
CherryPick.openSafeScope(scopeName: 'app.feature.auth.login');
|
||
print('✅ Complex scope created: ${complexScope.isCycleDetectionEnabled}');
|
||
print('');
|
||
|
||
// Example 6: Tracking resolution chains
|
||
print('6. Tracking dependency resolution chains:');
|
||
|
||
final trackingScope = CherryPick.openSafeRootScope();
|
||
trackingScope.installModules([
|
||
DatabaseModule(),
|
||
ApiModule(),
|
||
UserModule(),
|
||
]);
|
||
|
||
print(' Chain before resolve: ${CherryPick.getCurrentResolutionChain()}');
|
||
|
||
// The chain is populated during resolution, but cleared after completion
|
||
// ignore: unused_local_variable
|
||
final trackedUserService = trackingScope.resolve<UserService>();
|
||
print(' Chain after resolve: ${CherryPick.getCurrentResolutionChain()}');
|
||
print('');
|
||
|
||
// Example 7: Usage recommendations
|
||
print('7. Recommended usage:');
|
||
print('');
|
||
|
||
print('🔧 Development mode:');
|
||
print(' CherryPick.enableGlobalCycleDetection(); // Enable globally');
|
||
print(' or');
|
||
print(' final scope = CherryPick.openSafeRootScope(); // Safe scope');
|
||
print('');
|
||
|
||
print('🚀 Production mode:');
|
||
print(
|
||
' CherryPick.disableGlobalCycleDetection(); // Disable for performance');
|
||
print(' final scope = CherryPick.openRootScope(); // Regular scope');
|
||
print('');
|
||
|
||
print('🧪 Testing:');
|
||
print(' setUp(() => CherryPick.enableGlobalCycleDetection());');
|
||
print(' tearDown(() => CherryPick.closeRootScope());');
|
||
print('');
|
||
|
||
print('🎯 Feature-specific:');
|
||
print(
|
||
' CherryPick.enableCycleDetectionForScope(scopeName: "feature.critical");');
|
||
print(' // Enable only for critical features');
|
||
|
||
// Cleanup
|
||
CherryPick.closeRootScope();
|
||
CherryPick.disableGlobalCycleDetection();
|
||
|
||
print('\n=== Demonstration complete ===');
|
||
}
|