Named singletons

This commit is contained in:
Tobe O 2018-10-22 11:35:35 -04:00
parent 72d845e817
commit 5e13882560
3 changed files with 39 additions and 1 deletions

View file

@ -1,5 +1,6 @@
# 1.0.0-alpha.10
* Added `Container.registerLazySingleton<T>`.
* Added named singleton support.
# 1.0.0-alpha.9
* Added `Container.has<T>`.

View file

@ -21,9 +21,15 @@ void main() {
// Use `make` to create an instance.
var truck = container.make<Truck>();
// Register a named singleton.
container.registerNamedSingleton('the_truck', truck);
// Should print: 'Vroom! I have 40 horsepower in my engine.'
truck.drive();
// Should print the same.
container.findByName<Truck>('the_truck').drive();
// We can make a child container with its own factory.
var childContainer = container.createChild();

View file

@ -5,6 +5,7 @@ class Container {
final Reflector reflector;
final Map<Type, dynamic> _singletons = {};
final Map<Type, dynamic Function(Container)> _factories = {};
final Map<String, dynamic> _namedSingletons = {};
final Container _parent;
Container(this.reflector) : _parent = null;
@ -93,7 +94,7 @@ class Container {
}
/// Shorthand for registering a factory that injects a singleton when it runs.
///
///
/// In many cases, you might prefer this to [registerFactory].
void registerLazySingleton<T>(T Function(Container) f, {Type as}) {
registerFactory<T>(
@ -126,4 +127,34 @@ class Container {
_singletons[as ?? object.runtimeType] = object;
}
/// Finds a named singleton.
///
/// In general, prefer using [registerSingleton] and [registerFactory].
///
/// [findByName] is best reserved for internal logic that end users of code should
/// not see.
T findByName<T>(String name) {
if (_namedSingletons.containsKey(name)) {
return _namedSingletons[name] as T;
} else if (_parent != null) {
return _parent.findByName<T>(name);
} else {
throw new StateError(
'This container does not have a singleton named "$name".');
}
}
/// Registers a *named* singleton.
///
/// Note that this is not related to type-based injections, and exists as a mechanism
/// to enable injecting multiple instances of a type within the same container hierarchy.
void registerNamedSingleton<T>(String name, T object) {
if (_namedSingletons.containsKey(name)) {
throw new StateError(
'This container already has a singleton named "$name".');
}
_namedSingletons[name] = object;
}
}