import 'package:benchmark_di/scenarios/universal_binding_mode.dart'; import 'package:benchmark_di/scenarios/universal_scenario.dart'; import 'package:benchmark_di/scenarios/universal_service.dart'; import 'package:kiwi/kiwi.dart'; import 'di_adapter.dart'; /// DIAdapter-для KiwiContainer с поддержкой universal benchmark сценариев. class KiwiAdapter extends DIAdapter { late KiwiContainer _container; final bool _isSubScope; KiwiAdapter({KiwiContainer? container, bool isSubScope = false}) : _isSubScope = isSubScope { _container = container ?? KiwiContainer(); } @override void setupDependencies(void Function(KiwiContainer container) registration) { registration(_container); } @override Registration universalRegistration({ required S scenario, required int chainCount, required int nestingDepth, required UniversalBindingMode bindingMode, }) { if (scenario is UniversalScenario) { if (scenario == UniversalScenario.asyncChain || bindingMode == UniversalBindingMode.asyncStrategy) { throw UnsupportedError('Kiwi does not support async dependencies or async binding scenarios.'); } return (container) { switch (scenario) { case UniversalScenario.asyncChain: break; case UniversalScenario.register: container.registerSingleton( (c) => UniversalServiceImpl(value: 'reg', dependency: null), ); break; case UniversalScenario.named: container.registerFactory( (c) => UniversalServiceImpl(value: 'impl1'), name: 'impl1'); container.registerFactory( (c) => UniversalServiceImpl(value: 'impl2'), name: 'impl2'); break; case UniversalScenario.chain: for (int chain = 1; chain <= chainCount; chain++) { for (int level = 1; level <= nestingDepth; level++) { final prevDepName = '${chain}_${level - 1}'; final depName = '${chain}_$level'; switch (bindingMode) { case UniversalBindingMode.singletonStrategy: container.registerSingleton( (c) => UniversalServiceImpl( value: depName, dependency: level > 1 ? c.resolve(prevDepName) : null), name: depName); break; case UniversalBindingMode.factoryStrategy: container.registerFactory( (c) => UniversalServiceImpl( value: depName, dependency: level > 1 ? c.resolve(prevDepName) : null), name: depName); break; case UniversalBindingMode.asyncStrategy: // Не поддерживается break; } } } final depName = '${chainCount}_$nestingDepth'; container.registerSingleton( (c) => c.resolve(depName)); break; case UniversalScenario.override: final depName = '${chainCount}_$nestingDepth'; container.registerSingleton( (c) => c.resolve(depName)); break; } }; } throw UnsupportedError('Scenario $scenario not supported by KiwiAdapter'); } @override T resolve({String? named}) { // Для asyncChain нужен resolve> if (T.toString().startsWith('Future<')) { return _container.resolve(named); } else { return _container.resolve(named); } } @override Future resolveAsync({String? named}) async { if (T.toString().startsWith('Future<')) { // resolve>, unwrap result return Future.value(_container.resolve(named)); } else { // Для совместимости с chain/override return Future.value(_container.resolve(named)); } } @override void teardown() { _container.clear(); } @override KiwiAdapter openSubScope(String name) { // Возвращаем новый scoped контейнер (отдельный). Наследование не реализовано. return KiwiAdapter(container: KiwiContainer.scoped(), isSubScope: true); } @override Future waitForAsyncReady() async {} }