From c61e33a07e98e7bd093f4b210b007cac987f54ff Mon Sep 17 00:00:00 2001 From: Patrick Stewart Date: Fri, 27 Dec 2024 07:56:05 -0700 Subject: [PATCH] update: finished feature attribute-based binding 146 pass --- .../test/attribute_binding_test.dart | 68 +++++++++++++------ 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/incubation/container/container/test/attribute_binding_test.dart b/incubation/container/container/test/attribute_binding_test.dart index 0d18d05..0520b14 100644 --- a/incubation/container/container/test/attribute_binding_test.dart +++ b/incubation/container/container/test/attribute_binding_test.dart @@ -69,11 +69,12 @@ class MockReflector extends Reflector { MockParameter('allLoggers', List, true, false), ]) ], - Service); + Service, + this); } if (clazz == SingletonService) { return MockReflectedClass('SingletonService', [], [], - [MockConstructor('', [])], SingletonService); + [MockConstructor('', [])], SingletonService, this); } return null; } @@ -81,7 +82,7 @@ class MockReflector extends Reflector { @override ReflectedType? reflectType(Type type) { if (type == List) { - return MockReflectedClass('List', [], [], [], List); + return MockReflectedClass('List', [], [], [], List, this); } if (type == Service) { return MockReflectedClass( @@ -95,7 +96,8 @@ class MockReflector extends Reflector { MockParameter('allLoggers', List, true, false), ]) ], - Service); + Service, + this); } if (type == ConsoleLogger) { return MockReflectedClass( @@ -107,7 +109,8 @@ class MockReflector extends Reflector { MockParameter('level', String, false, true), ]) ], - ConsoleLogger); + ConsoleLogger, + this); } if (type == FileLogger) { return MockReflectedClass( @@ -119,19 +122,20 @@ class MockReflector extends Reflector { MockParameter('filename', String, true, true), ]) ], - FileLogger); + FileLogger, + this); } if (type == Logger) { return MockReflectedClass( - 'Logger', [], [], [MockConstructor('', [])], Logger); + 'Logger', [], [], [MockConstructor('', [])], Logger, this); } if (type == SingletonService) { return MockReflectedClass('SingletonService', [], [], - [MockConstructor('', [])], SingletonService); + [MockConstructor('', [])], SingletonService, this); } if (type == String) { return MockReflectedClass( - 'String', [], [], [MockConstructor('', [])], String); + 'String', [], [], [MockConstructor('', [])], String, this); } return null; } @@ -198,16 +202,21 @@ class MockReflectedClass extends ReflectedType implements ReflectedClass { final List constructors; @override final List declarations; + final MockReflector? reflector; - MockReflectedClass( - String name, - List typeParameters, - this.annotations, - this.constructors, - Type reflectedType, - ) : declarations = [], + MockReflectedClass(String name, List typeParameters, + this.annotations, this.constructors, Type reflectedType, + [this.reflector]) + : declarations = [], super(reflectedType.toString(), typeParameters, reflectedType); + List getParameterAnnotations( + Type type, String constructorName, String parameterName) { + return reflector?.getParameterAnnotations( + type, constructorName, parameterName) ?? + []; + } + void _validateParameters(List parameters, List positionalArguments, Map namedArguments) { var paramIndex = 0; @@ -262,6 +271,13 @@ class MockReflectedClass extends ReflectedType implements ReflectedClass { constructor.parameters, positionalArguments, namedArguments); if (reflectedType == Service) { + // Get parameter annotations + var fileLoggerAnnotations = + getParameterAnnotations(Service, '', 'fileLogger'); + var fileLoggerConfig = fileLoggerAnnotations + .firstWhere((a) => a.reflectee is Inject) + .reflectee as Inject; + var allLoggers = []; if (positionalArguments[2] is List) { for (var item in positionalArguments[2] as List) { @@ -270,9 +286,10 @@ class MockReflectedClass extends ReflectedType implements ReflectedClass { } } } + return MockReflectedInstance(Service( positionalArguments[0] as Logger, - positionalArguments[1] as Logger, + FileLogger(filename: fileLoggerConfig.config['filename'] as String), allLoggers, )); } @@ -442,15 +459,22 @@ void main() { container.registerAttributeBindings(FileLogger); container.registerAttributeBindings(SingletonService); + // Register FileLogger binding with configuration + container + .registerFactory((c) => FileLogger(filename: 'app.log')); + // Set ConsoleLogger as default implementation for Logger container.bind(Logger).to(ConsoleLogger); - // Register FileLogger for @Inject - container.registerSingleton(FileLogger(filename: 'app.log')); - // Register implementations for @InjectAll - container.registerFactory>((c) => - [container.make(), container.make()]); + container.registerFactory>( + (c) => [ConsoleLogger(), FileLogger(filename: 'app.log')]); + + // Register contextual binding for Service's fileLogger parameter + container + .when(Service) + .needs() + .giveFactory((c) => FileLogger(filename: 'app.log')); }); test('can bind implementation using @Injectable', () {