diff --git a/lib/src/core/hooked_service.dart b/lib/src/core/hooked_service.dart index fe499fb2..a8cd6fa6 100644 --- a/lib/src/core/hooked_service.dart +++ b/lib/src/core/hooked_service.dart @@ -493,7 +493,7 @@ class HookedServiceEvent> { /// Resolves a service from the application. /// /// Shorthand for `e.service.app.service(...)`. - Service getService(Pattern path) => service.app.service(path); + Service getService(Pattern path) => service.app.findService(path); bool _canceled = false; String _eventName; diff --git a/lib/src/core/routable.dart b/lib/src/core/routable.dart index b3c179a5..782ac4f3 100644 --- a/lib/src/core/routable.dart +++ b/lib/src/core/routable.dart @@ -44,6 +44,7 @@ RequestHandler chain(Iterable handlers) { /// A routable server that can handle dynamic requests. class Routable extends Router { final Map _services = {}; + final Map _serviceLookups = {}; final Map configuration = {}; final Container _container; @@ -73,9 +74,18 @@ class Routable extends Router { Stream get onService => _onService.stream; /// Retrieves the service assigned to the given path. - Service service(Pattern path) => - _services[path] ?? - _services[path.toString().replaceAll(_straySlashes, '')]; + T findService(Pattern path) { + return _serviceLookups.putIfAbsent(path, () { + return _services[path] ?? + _services[path.toString().replaceAll(_straySlashes, '')]; + }) as T; + } + + /// Shorthand for finding a [HookedService] in a statically-typed + HookedService findHookedService( + Pattern path) { + return findService(path) as HookedService; + } @override Route addRoute( diff --git a/test/hooked_test.dart b/test/hooked_test.dart index 97fc4980..2dbee135 100644 --- a/test/hooked_test.dart +++ b/test/hooked_test.dart @@ -16,16 +16,17 @@ main() { HttpServer server; String url; http.Client client; - HookedService Todos; + HookedService todoService; setUp(() async { app = new Angel(reflector: MirrorsReflector()); client = new http.Client(); app.use('/todos', new MapService()); app.use('/books', new BookService()); - Todos = app.service("todos") as HookedService; - Todos.beforeAllStream().listen((e) { + todoService = app.findHookedService('todos'); + + todoService.beforeAllStream().listen((e) { print('Fired ${e.eventName}! Data: ${e.data}; Params: ${e.params}'); }); @@ -43,13 +44,13 @@ main() { url = null; client.close(); client = null; - Todos = null; + todoService = null; }); test("listen before and after", () async { int count = 0; - Todos + todoService ..beforeIndexed.listen((_) { count++; }) @@ -63,7 +64,7 @@ main() { }); test("cancel before", () async { - Todos.beforeCreated + todoService.beforeCreated ..listen((HookedServiceEvent event) { event.cancel({"hello": "hooked world"}); }) @@ -80,7 +81,7 @@ main() { }); test("cancel after", () async { - Todos.afterIndexed + todoService.afterIndexed ..listen((HookedServiceEvent event) async { // Hooks can be Futures ;) event.cancel([ @@ -106,7 +107,7 @@ main() { }); test('inject request + response', () async { - HookedService books = app.service('books'); + HookedService books = app.findService('books'); books.beforeIndexed.listen((e) { expect([e.request, e.response], everyElement(isNotNull));