Files
cherrypick/cherrypick/example/cherrypick_helper_example.dart

231 lines
7.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 ===');
}