mirror of
https://github.com/pese-git/cherrypick.git
synced 2026-01-23 21:13:35 +00:00
feat(benchmark_di): add Kiwi DI adapter and CLI integration
This commit is contained in:
@@ -16,6 +16,8 @@ import 'package:benchmark_di/benchmarks/universal_chain_async_benchmark.dart';
|
|||||||
import 'package:benchmark_di/di_adapters/cherrypick_adapter.dart';
|
import 'package:benchmark_di/di_adapters/cherrypick_adapter.dart';
|
||||||
import 'package:benchmark_di/di_adapters/get_it_adapter.dart';
|
import 'package:benchmark_di/di_adapters/get_it_adapter.dart';
|
||||||
import 'package:benchmark_di/di_adapters/riverpod_adapter.dart';
|
import 'package:benchmark_di/di_adapters/riverpod_adapter.dart';
|
||||||
|
import 'package:benchmark_di/di_adapters/kiwi_adapter.dart';
|
||||||
|
import 'package:kiwi/kiwi.dart';
|
||||||
|
|
||||||
/// Command-line interface (CLI) runner for benchmarks.
|
/// Command-line interface (CLI) runner for benchmarks.
|
||||||
///
|
///
|
||||||
@@ -61,11 +63,40 @@ class BenchmarkCliRunner {
|
|||||||
repeats: config.repeats,
|
repeats: config.repeats,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
} else if (config.di == 'kiwi') {
|
||||||
|
final di = KiwiAdapter();
|
||||||
|
if (scenario == UniversalScenario.asyncChain) {
|
||||||
|
// UnsupportedError будет выброшен адаптером, но если дойдёт — вызывать async benchmark
|
||||||
|
final benchAsync = UniversalChainAsyncBenchmark<KiwiContainer>(
|
||||||
|
di,
|
||||||
|
chainCount: c,
|
||||||
|
nestingDepth: d,
|
||||||
|
mode: mode,
|
||||||
|
);
|
||||||
|
benchResult = await BenchmarkRunner.runAsync(
|
||||||
|
benchmark: benchAsync,
|
||||||
|
warmups: config.warmups,
|
||||||
|
repeats: config.repeats,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
final benchSync = UniversalChainBenchmark<KiwiContainer>(
|
||||||
|
di,
|
||||||
|
chainCount: c,
|
||||||
|
nestingDepth: d,
|
||||||
|
mode: mode,
|
||||||
|
scenario: scenario,
|
||||||
|
);
|
||||||
|
benchResult = await BenchmarkRunner.runSync(
|
||||||
|
benchmark: benchSync,
|
||||||
|
warmups: config.warmups,
|
||||||
|
repeats: config.repeats,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else if (config.di == 'riverpod') {
|
} else if (config.di == 'riverpod') {
|
||||||
final di = RiverpodAdapter();
|
final di = RiverpodAdapter();
|
||||||
if (scenario == UniversalScenario.asyncChain) {
|
if (scenario == UniversalScenario.asyncChain) {
|
||||||
final benchAsync = UniversalChainAsyncBenchmark<
|
final benchAsync = UniversalChainAsyncBenchmark<
|
||||||
Map<String, rp.ProviderBase<Object?>>>(
|
Map<String, rp.ProviderBase<Object?>>> (
|
||||||
di,
|
di,
|
||||||
chainCount: c,
|
chainCount: c,
|
||||||
nestingDepth: d,
|
nestingDepth: d,
|
||||||
@@ -78,7 +109,7 @@ class BenchmarkCliRunner {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final benchSync = UniversalChainBenchmark<
|
final benchSync = UniversalChainBenchmark<
|
||||||
Map<String, rp.ProviderBase<Object?>>>(
|
Map<String, rp.ProviderBase<Object?>>> (
|
||||||
di,
|
di,
|
||||||
chainCount: c,
|
chainCount: c,
|
||||||
nestingDepth: d,
|
nestingDepth: d,
|
||||||
|
|||||||
128
benchmark_di/lib/di_adapters/kiwi_adapter.dart
Normal file
128
benchmark_di/lib/di_adapters/kiwi_adapter.dart
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
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<KiwiContainer> {
|
||||||
|
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<KiwiContainer> universalRegistration<S extends Enum>({
|
||||||
|
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<UniversalService>(
|
||||||
|
(c) => UniversalServiceImpl(value: 'reg', dependency: null),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case UniversalScenario.named:
|
||||||
|
container.registerFactory<UniversalService>(
|
||||||
|
(c) => UniversalServiceImpl(value: 'impl1'), name: 'impl1');
|
||||||
|
container.registerFactory<UniversalService>(
|
||||||
|
(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<UniversalService>(
|
||||||
|
(c) => UniversalServiceImpl(
|
||||||
|
value: depName,
|
||||||
|
dependency: level > 1
|
||||||
|
? c.resolve<UniversalService>(prevDepName)
|
||||||
|
: null),
|
||||||
|
name: depName);
|
||||||
|
break;
|
||||||
|
case UniversalBindingMode.factoryStrategy:
|
||||||
|
container.registerFactory<UniversalService>(
|
||||||
|
(c) => UniversalServiceImpl(
|
||||||
|
value: depName,
|
||||||
|
dependency: level > 1
|
||||||
|
? c.resolve<UniversalService>(prevDepName)
|
||||||
|
: null),
|
||||||
|
name: depName);
|
||||||
|
break;
|
||||||
|
case UniversalBindingMode.asyncStrategy:
|
||||||
|
// Не поддерживается
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final depName = '${chainCount}_$nestingDepth';
|
||||||
|
container.registerSingleton<UniversalService>(
|
||||||
|
(c) => c.resolve<UniversalService>(depName));
|
||||||
|
break;
|
||||||
|
case UniversalScenario.override:
|
||||||
|
final depName = '${chainCount}_$nestingDepth';
|
||||||
|
container.registerSingleton<UniversalService>(
|
||||||
|
(c) => c.resolve<UniversalService>(depName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw UnsupportedError('Scenario $scenario not supported by KiwiAdapter');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
T resolve<T extends Object>({String? named}) {
|
||||||
|
// Для asyncChain нужен resolve<Future<T>>
|
||||||
|
if (T.toString().startsWith('Future<')) {
|
||||||
|
return _container.resolve<T>(named);
|
||||||
|
} else {
|
||||||
|
return _container.resolve<T>(named);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<T> resolveAsync<T extends Object>({String? named}) async {
|
||||||
|
if (T.toString().startsWith('Future<')) {
|
||||||
|
// resolve<Future<T>>, unwrap result
|
||||||
|
return Future.value(_container.resolve<T>(named));
|
||||||
|
} else {
|
||||||
|
// Для совместимости с chain/override
|
||||||
|
return Future.value(_container.resolve<T>(named));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void teardown() {
|
||||||
|
_container.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
KiwiAdapter openSubScope(String name) {
|
||||||
|
// Возвращаем новый scoped контейнер (отдельный). Наследование не реализовано.
|
||||||
|
return KiwiAdapter(container: KiwiContainer.scoped(), isSubScope: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> waitForAsyncReady() async {}
|
||||||
|
}
|
||||||
@@ -47,7 +47,7 @@ packages:
|
|||||||
path: "../cherrypick"
|
path: "../cherrypick"
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "3.0.0-dev.9"
|
version: "3.0.0-dev.10"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -72,6 +72,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.2.0"
|
version: "8.2.0"
|
||||||
|
kiwi:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: kiwi
|
||||||
|
sha256: d078364a90fb1b93852bb74468efdf4aaae35c036c538c1cf4f9c74a19df9a61
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.1"
|
||||||
lazy_memo:
|
lazy_memo:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ dependencies:
|
|||||||
args: ^2.7.0
|
args: ^2.7.0
|
||||||
get_it: ^8.2.0
|
get_it: ^8.2.0
|
||||||
riverpod: ^2.6.1
|
riverpod: ^2.6.1
|
||||||
|
kiwi: ^5.0.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lints: ^5.0.0
|
lints: ^5.0.0
|
||||||
|
|||||||
Reference in New Issue
Block a user