From 5e1388256077e8376e8568417ea937190277bd62 Mon Sep 17 00:00:00 2001 From: Tobe O Date: Mon, 22 Oct 2018 11:35:35 -0400 Subject: [PATCH] Named singletons --- angel_container/CHANGELOG.md | 1 + angel_container/example/main.dart | 6 +++++ angel_container/lib/src/container.dart | 33 +++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/angel_container/CHANGELOG.md b/angel_container/CHANGELOG.md index 77dcb4e8..134f0511 100644 --- a/angel_container/CHANGELOG.md +++ b/angel_container/CHANGELOG.md @@ -1,5 +1,6 @@ # 1.0.0-alpha.10 * Added `Container.registerLazySingleton`. +* Added named singleton support. # 1.0.0-alpha.9 * Added `Container.has`. diff --git a/angel_container/example/main.dart b/angel_container/example/main.dart index 0a05e774..47108b08 100644 --- a/angel_container/example/main.dart +++ b/angel_container/example/main.dart @@ -21,9 +21,15 @@ void main() { // Use `make` to create an instance. var truck = container.make(); + // 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('the_truck').drive(); + // We can make a child container with its own factory. var childContainer = container.createChild(); diff --git a/angel_container/lib/src/container.dart b/angel_container/lib/src/container.dart index 07bfd87f..c445d128 100644 --- a/angel_container/lib/src/container.dart +++ b/angel_container/lib/src/container.dart @@ -5,6 +5,7 @@ class Container { final Reflector reflector; final Map _singletons = {}; final Map _factories = {}; + final Map _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 Function(Container) f, {Type as}) { registerFactory( @@ -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(String name) { + if (_namedSingletons.containsKey(name)) { + return _namedSingletons[name] as T; + } else if (_parent != null) { + return _parent.findByName(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(String name, T object) { + if (_namedSingletons.containsKey(name)) { + throw new StateError( + 'This container already has a singleton named "$name".'); + } + + _namedSingletons[name] = object; + } }