2025-08-07 14:11:29 +03:00
|
|
|
|
import 'package:benchmark_di/scenarios/universal_chain_module.dart';
|
|
|
|
|
|
import 'package:benchmark_di/scenarios/universal_service.dart';
|
2025-08-07 09:15:26 +03:00
|
|
|
|
import 'package:get_it/get_it.dart';
|
|
|
|
|
|
import 'di_adapter.dart';
|
|
|
|
|
|
|
2025-08-07 13:44:39 +03:00
|
|
|
|
/// Универсальный DIAdapter для GetIt c поддержкой scopes и строгой типизацией.
|
|
|
|
|
|
class GetItAdapter extends DIAdapter<GetIt> {
|
2025-08-07 09:15:26 +03:00
|
|
|
|
late GetIt _getIt;
|
2025-08-07 13:44:39 +03:00
|
|
|
|
final String? _scopeName;
|
|
|
|
|
|
final bool _isSubScope;
|
2025-08-07 12:11:16 +03:00
|
|
|
|
bool _scopePushed = false;
|
|
|
|
|
|
|
2025-08-07 13:44:39 +03:00
|
|
|
|
/// Основной (root) и subScope-конструкторы.
|
|
|
|
|
|
GetItAdapter({GetIt? instance, String? scopeName, bool isSubScope = false})
|
|
|
|
|
|
: _scopeName = scopeName,
|
|
|
|
|
|
_isSubScope = isSubScope {
|
|
|
|
|
|
if (instance != null) {
|
|
|
|
|
|
_getIt = instance;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-07 12:11:16 +03:00
|
|
|
|
|
|
|
|
|
|
@override
|
2025-08-07 13:44:39 +03:00
|
|
|
|
void setupDependencies(void Function(GetIt container) registration) {
|
|
|
|
|
|
if (_isSubScope) {
|
|
|
|
|
|
// Создаём scope через pushNewScope с init
|
|
|
|
|
|
_getIt.pushNewScope(
|
|
|
|
|
|
scopeName: _scopeName,
|
|
|
|
|
|
init: (getIt) => registration(getIt),
|
|
|
|
|
|
);
|
|
|
|
|
|
_scopePushed = true;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
_getIt = GetIt.asNewInstance();
|
|
|
|
|
|
registration(_getIt);
|
|
|
|
|
|
}
|
2025-08-07 12:11:16 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
2025-08-07 13:44:39 +03:00
|
|
|
|
T resolve<T extends Object>({String? named}) =>
|
|
|
|
|
|
_getIt<T>(instanceName: named);
|
2025-08-07 12:11:16 +03:00
|
|
|
|
|
|
|
|
|
|
@override
|
2025-08-07 13:44:39 +03:00
|
|
|
|
Future<T> resolveAsync<T extends Object>({String? named}) async =>
|
|
|
|
|
|
_getIt<T>(instanceName: named);
|
2025-08-07 12:11:16 +03:00
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
void teardown() {
|
2025-08-07 13:44:39 +03:00
|
|
|
|
if (_isSubScope && _scopePushed) {
|
2025-08-07 12:11:16 +03:00
|
|
|
|
_getIt.popScope();
|
|
|
|
|
|
_scopePushed = false;
|
2025-08-07 13:44:39 +03:00
|
|
|
|
} else {
|
|
|
|
|
|
_getIt.reset();
|
2025-08-07 12:11:16 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
2025-08-07 13:44:39 +03:00
|
|
|
|
GetItAdapter openSubScope(String name) =>
|
|
|
|
|
|
GetItAdapter(instance: _getIt, scopeName: name, isSubScope: true);
|
2025-08-07 09:15:26 +03:00
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
Future<void> waitForAsyncReady() async {
|
|
|
|
|
|
await _getIt.allReady();
|
|
|
|
|
|
}
|
2025-08-07 14:11:29 +03:00
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
Registration<GetIt> universalRegistration<S extends Enum>({
|
|
|
|
|
|
required S scenario,
|
|
|
|
|
|
required int chainCount,
|
|
|
|
|
|
required int nestingDepth,
|
|
|
|
|
|
required UniversalBindingMode bindingMode,
|
|
|
|
|
|
}) {
|
|
|
|
|
|
if (scenario is UniversalScenario) {
|
|
|
|
|
|
return (getIt) {
|
|
|
|
|
|
switch (scenario) {
|
|
|
|
|
|
case UniversalScenario.asyncChain:
|
|
|
|
|
|
for (int chain = 1; chain <= chainCount; chain++) {
|
|
|
|
|
|
for (int level = 1; level <= nestingDepth; level++) {
|
|
|
|
|
|
final prevDepName = '${chain}_${level - 1}';
|
|
|
|
|
|
final depName = '${chain}_$level';
|
|
|
|
|
|
getIt.registerSingletonAsync<UniversalService>(
|
|
|
|
|
|
() async {
|
|
|
|
|
|
final prev = level > 1
|
|
|
|
|
|
? await getIt.getAsync<UniversalService>(instanceName: prevDepName)
|
|
|
|
|
|
: null;
|
|
|
|
|
|
return UniversalServiceImpl(value: depName, dependency: prev);
|
|
|
|
|
|
},
|
|
|
|
|
|
instanceName: depName,
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UniversalScenario.register:
|
|
|
|
|
|
getIt.registerSingleton<UniversalService>(UniversalServiceImpl(value: 'reg', dependency: null));
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UniversalScenario.named:
|
|
|
|
|
|
getIt.registerFactory<UniversalService>(() => UniversalServiceImpl(value: 'impl1'), instanceName: 'impl1');
|
|
|
|
|
|
getIt.registerFactory<UniversalService>(() => UniversalServiceImpl(value: 'impl2'), instanceName: '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:
|
|
|
|
|
|
getIt.registerSingleton<UniversalService>(
|
|
|
|
|
|
UniversalServiceImpl(
|
|
|
|
|
|
value: depName,
|
|
|
|
|
|
dependency: level > 1
|
|
|
|
|
|
? getIt<UniversalService>(instanceName: prevDepName)
|
|
|
|
|
|
: null,
|
|
|
|
|
|
),
|
|
|
|
|
|
instanceName: depName,
|
|
|
|
|
|
);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UniversalBindingMode.factoryStrategy:
|
|
|
|
|
|
getIt.registerFactory<UniversalService>(
|
|
|
|
|
|
() => UniversalServiceImpl(
|
|
|
|
|
|
value: depName,
|
|
|
|
|
|
dependency: level > 1
|
|
|
|
|
|
? getIt<UniversalService>(instanceName: prevDepName)
|
|
|
|
|
|
: null,
|
|
|
|
|
|
),
|
|
|
|
|
|
instanceName: depName,
|
|
|
|
|
|
);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UniversalBindingMode.asyncStrategy:
|
|
|
|
|
|
getIt.registerSingletonAsync<UniversalService>(
|
|
|
|
|
|
() async => UniversalServiceImpl(
|
|
|
|
|
|
value: depName,
|
|
|
|
|
|
dependency: level > 1
|
|
|
|
|
|
? await getIt.getAsync<UniversalService>(instanceName: prevDepName)
|
|
|
|
|
|
: null,
|
|
|
|
|
|
),
|
|
|
|
|
|
instanceName: depName,
|
|
|
|
|
|
);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UniversalScenario.override:
|
|
|
|
|
|
// handled at benchmark level
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (scenario == UniversalScenario.chain || scenario == UniversalScenario.override) {
|
|
|
|
|
|
final depName = '${chainCount}_$nestingDepth';
|
|
|
|
|
|
getIt.registerSingleton<UniversalService>(
|
|
|
|
|
|
getIt<UniversalService>(instanceName: depName),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
throw UnsupportedError('Scenario $scenario not supported by GetItAdapter');
|
|
|
|
|
|
}
|
2025-08-07 09:15:26 +03:00
|
|
|
|
}
|