import 'package:cherrypick/cherrypick.dart'; // Пример сервисов с циклической зависимостью class UserService { final OrderService orderService; UserService(this.orderService); void createUser(String name) { print('Creating user: $name'); // Пытаемся получить заказы пользователя, что создает циклическую зависимость orderService.getOrdersForUser(name); } } class OrderService { final UserService userService; OrderService(this.userService); void getOrdersForUser(String userName) { print('Getting orders for user: $userName'); // Пытаемся получить информацию о пользователе, что создает циклическую зависимость userService.createUser(userName); } } // Модули с циклическими зависимостями class UserModule extends Module { @override void builder(Scope currentScope) { bind() .toProvide(() => UserService(currentScope.resolve())); } } class OrderModule extends Module { @override void builder(Scope currentScope) { bind() .toProvide(() => OrderService(currentScope.resolve())); } } // Правильная реализация без циклических зависимостей class UserRepository { void createUser(String name) { print('Creating user in repository: $name'); } String getUserInfo(String name) { return 'User info for: $name'; } } class OrderRepository { void createOrder(String orderId, String userName) { print('Creating order $orderId for user: $userName'); } List getOrdersForUser(String userName) { return ['order1', 'order2', 'order3']; } } class ImprovedUserService { final UserRepository userRepository; ImprovedUserService(this.userRepository); void createUser(String name) { userRepository.createUser(name); } String getUserInfo(String name) { return userRepository.getUserInfo(name); } } class ImprovedOrderService { final OrderRepository orderRepository; final ImprovedUserService userService; ImprovedOrderService(this.orderRepository, this.userService); void createOrder(String orderId, String userName) { // Проверяем, что пользователь существует final userInfo = userService.getUserInfo(userName); print('User exists: $userInfo'); orderRepository.createOrder(orderId, userName); } List getOrdersForUser(String userName) { return orderRepository.getOrdersForUser(userName); } } // Правильные модули без циклических зависимостей class ImprovedUserModule extends Module { @override void builder(Scope currentScope) { bind().singleton().toProvide(() => UserRepository()); bind().toProvide( () => ImprovedUserService(currentScope.resolve())); } } class ImprovedOrderModule extends Module { @override void builder(Scope currentScope) { bind().singleton().toProvide(() => OrderRepository()); bind().toProvide(() => ImprovedOrderService( currentScope.resolve(), currentScope.resolve())); } } void main() { print('=== Circular Dependency Detection Example ===\n'); // Example 1: Demonstrate circular dependency print('1. Attempt to create a scope with circular dependencies:'); try { final scope = CherryPick.openRootScope(); scope .enableCycleDetection(); // Включаем обнаружение циклических зависимостей scope.installModules([ UserModule(), OrderModule(), ]); // Это должно выбросить CircularDependencyException final userService = scope.resolve(); print('UserService created: $userService'); } catch (e) { print('❌ Circular dependency detected: $e\n'); } // Example 2: Without circular dependency detection (dangerous!) print('2. Same code without circular dependency detection:'); try { CherryPick.disableGlobalCrossScopeCycleDetection(); CherryPick.disableGlobalCycleDetection(); final scope = CherryPick.openRootScope(); // НЕ включаем обнаружение циклических зависимостей scope.installModules([ UserModule(), OrderModule(), ]); // Это приведет к StackOverflowError при попытке использования final userService = scope.resolve(); print('UserService создан: $userService'); // Попытка использовать сервис приведет к бесконечной рекурсии // userService.createUser('John'); // Раскомментируйте для демонстрации StackOverflow print('⚠️ UserService created, but using it will cause StackOverflow\n'); } catch (e) { print('❌ Error: $e\n'); } // Example 3: Correct architecture without circular dependencies print('3. Correct architecture without circular dependencies:'); try { final scope = CherryPick.openRootScope(); scope.enableCycleDetection(); // Включаем для безопасности scope.installModules([ ImprovedUserModule(), ImprovedOrderModule(), ]); final userService = scope.resolve(); final orderService = scope.resolve(); print('✅ Services created successfully'); // Демонстрация работы userService.createUser('John'); orderService.createOrder('ORD-001', 'John'); final orders = orderService.getOrdersForUser('John'); print('✅ Orders for user John: $orders'); } catch (e) { print('❌ Error: $e'); } print('\n=== Recommendations ==='); print('1. Always enable circular dependency detection in development mode.'); print('2. Use repositories and services to separate concerns.'); print('3. Avoid mutual dependencies between services at the same level.'); print('4. Use events or mediators to decouple components.'); }