platform/angel_container/lib/src/container.dart

58 lines
1.6 KiB
Dart
Raw Normal View History

2018-07-10 18:18:10 +00:00
import 'exception.dart';
import 'reflector.dart';
class Container {
final Reflector reflector;
final Map<Type, dynamic> _singletons = {};
Container(this.reflector);
T make<T>(Type type) {
if (_singletons.containsKey(type)) {
return _singletons[type] as T;
} else {
var reflectedType = reflector.reflectType(type);
var positional = [];
var named = <String, dynamic>{};
if (reflectedType is ReflectedClass) {
2018-08-11 19:07:35 +00:00
bool isDefault(String name) {
return name.isEmpty || name == reflectedType.name;
}
2018-07-10 18:18:10 +00:00
var constructor = reflectedType.constructors.firstWhere(
2018-08-11 19:07:35 +00:00
(c) => isDefault(c.name),
orElse: () => throw new ReflectionException(
'${reflectedType.name} has no default constructor, and therefore cannot be instantiated.'));
2018-07-10 18:18:10 +00:00
for (var param in constructor.parameters) {
2018-08-11 19:07:35 +00:00
var value = make(param.type.reflectedType);
2018-07-10 18:18:10 +00:00
if (param.isNamed) {
named[param.name] = value;
} else {
positional.add(value);
}
}
2018-08-11 19:07:35 +00:00
return reflectedType.newInstance(
isDefault(constructor.name) ? '' : constructor.name,
positional,
named, []);
2018-07-10 18:18:10 +00:00
} else {
throw new ReflectionException(
'$type is not a class, and therefore cannot be instantiated.');
}
}
}
void singleton(Object object, {Type as}) {
if (_singletons.containsKey(as ?? object.runtimeType)) {
2018-08-11 19:07:35 +00:00
throw new StateError(
'This container already has a singleton for ${as ?? object.runtimeType}.');
2018-07-10 18:18:10 +00:00
}
_singletons[as ?? object.runtimeType] = object;
}
}