diff --git a/cherrypick/lib/src/binding.dart b/cherrypick/lib/src/binding.dart index 78c6774..fe248c5 100644 --- a/cherrypick/lib/src/binding.dart +++ b/cherrypick/lib/src/binding.dart @@ -29,6 +29,7 @@ class Binding { late Type _key; late String _name; T? _instance; + Future? _instanceAsync; Provider? _provider; ProviderWithParams? _providerWithParams; @@ -94,6 +95,17 @@ class Binding { return this; } + /// RU: Инициализация экземляпяра [value]. + /// ENG: Initialization instance [value]. + /// + /// return [Binding] + Binding toInstanceAsync(Future value) { + _mode = Mode.instance; + _instanceAsync = value; + _isSingleton = true; + return this; + } + /// RU: Инициализация экземляпяра  через провайдер [value]. /// ENG: Initialization instance via provider [value]. /// @@ -149,6 +161,12 @@ class Binding { /// return [T] T? get instance => _instance; + /// RU: Поиск экземпляра. + /// ENG: Resolve instance. + /// + /// return [T] + Future? get instanceAsync => _instanceAsync; + /// RU: Поиск экземпляра. /// ENG: Resolve instance. /// diff --git a/cherrypick/lib/src/scope.dart b/cherrypick/lib/src/scope.dart index f0ac55d..cfc9ee1 100644 --- a/cherrypick/lib/src/scope.dart +++ b/cherrypick/lib/src/scope.dart @@ -160,11 +160,18 @@ class Scope { if (binding.key == T && ((!binding.isNamed && named == null) || (binding.isNamed && named == binding.name))) { + if (binding.instanceAsync != null) { + return await binding.instanceAsync; + } + if (binding.asyncProvider != null) { return await binding.asyncProvider?.call(); } if (binding.asyncProviderWithParams != null) { + if (params == null) { + throw StateError('Param is null. Maybe you forget pass it'); + } return await binding.asyncProviderWithParams!(params); } } diff --git a/cherrypick/test/src/binding_test.dart b/cherrypick/test/src/binding_test.dart index 9f69647..134257c 100644 --- a/cherrypick/test/src/binding_test.dart +++ b/cherrypick/test/src/binding_test.dart @@ -312,4 +312,83 @@ void main() { }); }); }); + + test('Binding returns null providerWithParams if not set', () { + final binding = Binding(); + expect(binding.providerWithParams(123), null); + }); + + test('Binding withName changes isNamed to true', () { + final binding = Binding().withName('foo'); + expect(binding.isNamed, true); + expect(binding.name, 'foo'); + }); + + // Проверка singleton provider вызывается один раз + test('Singleton provider only called once', () { + int counter = 0; + final binding = Binding().toProvide(() { + counter++; + return counter; + }).singleton(); + + final first = binding.provider; + final second = binding.provider; + expect(first, equals(second)); + expect(counter, 1); + }); + + // Повторный вызов toInstance влияет на значение + test('Multiple toInstance calls changes instance', () { + final binding = Binding().toInstance(1).toInstance(2); + expect(binding.instance, 2); + }); + + // Проверка mode после chaining + test('Chained withName and singleton preserves mode', () { + final binding = + Binding().toProvide(() => 3).withName("named").singleton(); + expect(binding.mode, Mode.providerInstance); + }); + + group('Check toInstanceAsync.', () { + test('Binding resolves instanceAsync with expected value', () async { + final expectedValue = 42; + final binding = + Binding().toInstanceAsync(Future.value(expectedValue)); + final result = await binding.instanceAsync; + expect(result, equals(expectedValue)); + }); + + test('Binding instanceAsync does not affect instance', () { + final binding = Binding().toInstanceAsync(Future.value(5)); + expect(binding.instance, null); + }); + + test('Binding mode is set to instance', () { + final binding = Binding().toInstanceAsync(Future.value(5)); + expect(binding.mode, Mode.instance); + }); + + test('Binding isSingleton is true after toInstanceAsync', () { + final binding = Binding().toInstanceAsync(Future.value(5)); + expect(binding.isSingleton, isTrue); + }); + + test('Binding withName combines with toInstanceAsync', () async { + final binding = Binding() + .withName('asyncValue') + .toInstanceAsync(Future.value(7)); + expect(binding.isNamed, isTrue); + expect(binding.name, 'asyncValue'); + expect(await binding.instanceAsync, 7); + }); + + test('Binding instanceAsync keeps value after multiple awaits', () async { + final binding = Binding().toInstanceAsync(Future.value(123)); + final result1 = await binding.instanceAsync; + final result2 = await binding.instanceAsync; + expect(result1, equals(result2)); + }); + }); }