refactor: testing 145 pass 1 fail
This commit is contained in:
parent
40eadbe408
commit
34b31a7059
2 changed files with 91 additions and 10 deletions
|
@ -1218,8 +1218,19 @@ class Container {
|
||||||
var value = injectAnnotation.reflectee;
|
var value = injectAnnotation.reflectee;
|
||||||
if (value is Inject) {
|
if (value is Inject) {
|
||||||
// Inject specific implementation with config
|
// Inject specific implementation with config
|
||||||
result.add(
|
result.add(withParameters(value.config, () {
|
||||||
withParameters(value.config, () => make(value.implementation)));
|
// First try to make the implementation directly
|
||||||
|
if (has(value.implementation)) {
|
||||||
|
return make(value.implementation);
|
||||||
|
}
|
||||||
|
// If that fails, try to resolve through contextual binding
|
||||||
|
var contextual = _getContextualConcrete(value.implementation);
|
||||||
|
if (contextual != null) {
|
||||||
|
return make(contextual);
|
||||||
|
}
|
||||||
|
// Finally try to make it normally
|
||||||
|
return make(value.implementation);
|
||||||
|
}));
|
||||||
} else if (value is InjectTagged) {
|
} else if (value is InjectTagged) {
|
||||||
// Inject tagged implementation
|
// Inject tagged implementation
|
||||||
var tagged = this.tagged(value.tag);
|
var tagged = this.tagged(value.tag);
|
||||||
|
@ -1248,6 +1259,7 @@ class Container {
|
||||||
/// Make all instances of a type
|
/// Make all instances of a type
|
||||||
List<dynamic> makeAll(Type type) {
|
List<dynamic> makeAll(Type type) {
|
||||||
var result = <dynamic>[];
|
var result = <dynamic>[];
|
||||||
|
var seen = <Type>{};
|
||||||
|
|
||||||
// Get all tagged implementations
|
// Get all tagged implementations
|
||||||
var allTags = _tags.entries
|
var allTags = _tags.entries
|
||||||
|
@ -1255,8 +1267,38 @@ class Container {
|
||||||
.map((entry) => entry.key)
|
.map((entry) => entry.key)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
// Collect implementations from all tags
|
||||||
for (var tag in allTags) {
|
for (var tag in allTags) {
|
||||||
result.addAll(tagged(tag));
|
var implementations =
|
||||||
|
_tags[tag]!.where((t) => !seen.contains(t)).where((t) {
|
||||||
|
var reflectedType = reflector.reflectType(t);
|
||||||
|
var targetType = reflector.reflectType(type);
|
||||||
|
return reflectedType != null &&
|
||||||
|
targetType != null &&
|
||||||
|
(reflectedType.isAssignableTo(targetType) || t == type);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
for (var impl in implementations) {
|
||||||
|
seen.add(impl);
|
||||||
|
result.add(make(impl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no tagged implementations found, try to get all registered implementations
|
||||||
|
if (result.isEmpty) {
|
||||||
|
var allTypes = [..._singletons.keys, ..._factories.keys];
|
||||||
|
for (var t in allTypes) {
|
||||||
|
if (!seen.contains(t)) {
|
||||||
|
var reflectedType = reflector.reflectType(t);
|
||||||
|
var targetType = reflector.reflectType(type);
|
||||||
|
if (reflectedType != null &&
|
||||||
|
targetType != null &&
|
||||||
|
(reflectedType.isAssignableTo(targetType) || t == type)) {
|
||||||
|
seen.add(t);
|
||||||
|
result.add(make(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -235,9 +235,19 @@ class MockReflectedClass extends ReflectedType implements ReflectedClass {
|
||||||
// Handle List<Logger> specially
|
// Handle List<Logger> specially
|
||||||
if (reflectedType == List<Logger>) {
|
if (reflectedType == List<Logger>) {
|
||||||
var loggers = <Logger>[];
|
var loggers = <Logger>[];
|
||||||
for (var arg in positionalArguments) {
|
if (positionalArguments.isNotEmpty) {
|
||||||
if (arg is Logger) {
|
if (positionalArguments[0] is List) {
|
||||||
loggers.add(arg);
|
for (var item in positionalArguments[0] as List) {
|
||||||
|
if (item is Logger) {
|
||||||
|
loggers.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (var item in positionalArguments) {
|
||||||
|
if (item is Logger) {
|
||||||
|
loggers.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MockReflectedInstance(loggers);
|
return MockReflectedInstance(loggers);
|
||||||
|
@ -252,18 +262,18 @@ class MockReflectedClass extends ReflectedType implements ReflectedClass {
|
||||||
constructor.parameters, positionalArguments, namedArguments);
|
constructor.parameters, positionalArguments, namedArguments);
|
||||||
|
|
||||||
if (reflectedType == Service) {
|
if (reflectedType == Service) {
|
||||||
var loggers = <Logger>[];
|
var allLoggers = <Logger>[];
|
||||||
if (positionalArguments[2] is List) {
|
if (positionalArguments[2] is List) {
|
||||||
for (var item in positionalArguments[2] as List) {
|
for (var item in positionalArguments[2] as List) {
|
||||||
if (item is Logger) {
|
if (item is Logger) {
|
||||||
loggers.add(item);
|
allLoggers.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MockReflectedInstance(Service(
|
return MockReflectedInstance(Service(
|
||||||
positionalArguments[0] as Logger,
|
positionalArguments[0] as Logger,
|
||||||
positionalArguments[1] as Logger,
|
positionalArguments[1] as Logger,
|
||||||
loggers,
|
allLoggers,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if (reflectedType == ConsoleLogger) {
|
if (reflectedType == ConsoleLogger) {
|
||||||
|
@ -286,12 +296,22 @@ class MockReflectedClass extends ReflectedType implements ReflectedClass {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isAssignableTo(ReflectedType? other) {
|
bool isAssignableTo(ReflectedType? other) {
|
||||||
|
// Handle primitive types and exact matches
|
||||||
|
if (reflectedType == other?.reflectedType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Handle Logger implementations
|
||||||
if (reflectedType == ConsoleLogger && other?.reflectedType == Logger) {
|
if (reflectedType == ConsoleLogger && other?.reflectedType == Logger) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (reflectedType == FileLogger && other?.reflectedType == Logger) {
|
if (reflectedType == FileLogger && other?.reflectedType == Logger) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// Handle List<Logger>
|
||||||
|
if (reflectedType.toString() == 'List<Logger>' &&
|
||||||
|
other?.reflectedType.toString() == 'List<Logger>') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,6 +384,18 @@ class MockReflectedType implements ReflectedType {
|
||||||
if (reflectedType == other?.reflectedType) {
|
if (reflectedType == other?.reflectedType) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// Handle Logger implementations
|
||||||
|
if (reflectedType == ConsoleLogger && other?.reflectedType == Logger) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (reflectedType == FileLogger && other?.reflectedType == Logger) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Handle List<Logger>
|
||||||
|
if (reflectedType.toString() == 'List<Logger>' &&
|
||||||
|
other?.reflectedType.toString() == 'List<Logger>') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,13 +437,20 @@ void main() {
|
||||||
// Reset instance count
|
// Reset instance count
|
||||||
SingletonService.instanceCount = 0;
|
SingletonService.instanceCount = 0;
|
||||||
|
|
||||||
// Register implementations
|
// Register implementations with attributes
|
||||||
container.registerAttributeBindings(ConsoleLogger);
|
container.registerAttributeBindings(ConsoleLogger);
|
||||||
container.registerAttributeBindings(FileLogger);
|
container.registerAttributeBindings(FileLogger);
|
||||||
container.registerAttributeBindings(SingletonService);
|
container.registerAttributeBindings(SingletonService);
|
||||||
|
|
||||||
// Set ConsoleLogger as default implementation for Logger
|
// Set ConsoleLogger as default implementation for Logger
|
||||||
container.bind(Logger).to(ConsoleLogger);
|
container.bind(Logger).to(ConsoleLogger);
|
||||||
|
|
||||||
|
// Register FileLogger for @Inject
|
||||||
|
container.registerSingleton(FileLogger(filename: 'app.log'));
|
||||||
|
|
||||||
|
// Register implementations for @InjectAll
|
||||||
|
container.registerFactory<List<Logger>>((c) =>
|
||||||
|
[container.make<ConsoleLogger>(), container.make<FileLogger>()]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can bind implementation using @Injectable', () {
|
test('can bind implementation using @Injectable', () {
|
||||||
|
|
Loading…
Reference in a new issue