From 0d64e101f44c2ca484c0f7b21f7a4ee19d52b3ca Mon Sep 17 00:00:00 2001 From: Tobe O Date: Sun, 21 Oct 2018 04:00:39 -0400 Subject: [PATCH] Custom container in handleContained --- CHANGELOG.md | 3 +++ lib/src/core/injection.dart | 17 ++++++++++------- lib/src/core/server.dart | 16 +++++++++------- pubspec.yaml | 2 +- test/di_test.dart | 10 ++++++++++ 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f522884..75feac3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 2.0.0-alpha.6 +* Allow passing a custom `Container` to `handleContained` and co. + # 2.0.0-alpha.5 * `MapService` methods now explicitly return `Map`. diff --git a/lib/src/core/injection.dart b/lib/src/core/injection.dart index ff086ee6..b4737273 100644 --- a/lib/src/core/injection.dart +++ b/lib/src/core/injection.dart @@ -23,8 +23,9 @@ RequestHandler ioc(Function handler, {Iterable optional: const []}) { } resolveInjection(requirement, InjectionRequest injection, RequestContext req, - ResponseContext res, bool throwOnUnresolved) { + ResponseContext res, bool throwOnUnresolved, [Container container]) { var propFromApp; + container ??= req?.container ?? res?.app?.container; if (requirement == RequestContext) { return req; @@ -56,11 +57,11 @@ resolveInjection(requirement, InjectionRequest injection, RequestContext req, if (req.params.containsKey(key) || req.app.configuration.containsKey(key) || _primitiveTypes.contains(type)) { - return resolveInjection(key, injection, req, res, throwOnUnresolved); + return resolveInjection(key, injection, req, res, throwOnUnresolved, container); } else - return resolveInjection(type, injection, req, res, throwOnUnresolved); + return resolveInjection(type, injection, req, res, throwOnUnresolved, container); } else if (requirement is Type && requirement != dynamic) { - return req.app.container.make(requirement); + return container.make(requirement); } else if (throwOnUnresolved) { throw new ArgumentError( '$requirement cannot be injected into a request handler.'); @@ -78,7 +79,8 @@ bool suitableForInjection( } /// Handles a request with a DI-enabled handler. -RequestHandler handleContained(Function handler, InjectionRequest injection) { +RequestHandler handleContained(Function handler, InjectionRequest injection, + [Container container]) { return (RequestContext req, ResponseContext res) { if (injection.parameters.isNotEmpty && injection.parameters.values.any((p) => p.match != null) && @@ -89,11 +91,12 @@ RequestHandler handleContained(Function handler, InjectionRequest injection) { Map named = {}; args.addAll(injection.required - .map((r) => resolveInjection(r, injection, req, res, true))); + .map((r) => resolveInjection(r, injection, req, res, true, container))); injection.named.forEach((k, v) { var name = new Symbol(k); - named[name] = resolveInjection([k, v], injection, req, res, false); + named[name] = + resolveInjection([k, v], injection, req, res, false, container); }); return Function.apply(handler, args, named); diff --git a/lib/src/core/server.dart b/lib/src/core/server.dart index 60d3c421..90167f65 100644 --- a/lib/src/core/server.dart +++ b/lib/src/core/server.dart @@ -306,24 +306,26 @@ class Angel extends Routable { /// Run a function after injecting from service container. /// If this function has been reflected before, then /// the execution will be faster, as the injection requirements were stored beforehand. - Future runContained( - Function handler, RequestContext req, ResponseContext res) { + Future runContained(Function handler, RequestContext req, ResponseContext res, + [Container container]) { return new Future.sync(() { if (_preContained.containsKey(handler)) { - return handleContained(handler, _preContained[handler])(req, res); + return handleContained(handler, _preContained[handler], container)( + req, res); } - return runReflected(handler, req, res); + return runReflected(handler, req, res, container); }); } /// Runs with DI, and *always* reflects. Prefer [runContained]. - Future runReflected( - Function handler, RequestContext req, ResponseContext res) { + Future runReflected(Function handler, RequestContext req, ResponseContext res, + [Container container]) { var h = handleContained( handler, _preContained[handler] = - preInject(handler, req.app.container.reflector)); + preInject(handler, req.app.container.reflector), + container); return new Future.sync(() => h(req, res)); // return closureMirror.apply(args).reflectee; } diff --git a/pubspec.yaml b/pubspec.yaml index ff50f815..3e8d1011 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_framework -version: 2.0.0-alpha.5 +version: 2.0.0-alpha.6 description: > A high-powered HTTP server with DI, routing and more. When combined with the other packages in the Angel ecosystem, this diff --git a/test/di_test.dart b/test/di_test.dart index 53bd5493..9d708273 100644 --- a/test/di_test.dart +++ b/test/di_test.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; +import 'package:angel_container/angel_container.dart'; import 'package:angel_container/mirrors.dart'; import 'package:angel_framework/angel_framework.dart'; import 'package:http/http.dart' as http; @@ -44,6 +45,15 @@ main() { await server.close(force: true); }); + test('runContained with custom container', () async { + var app = new Angel(); + var c = new Container(const EmptyReflector()); + c.registerSingleton(new Todo(text: 'Hey!')); + + var r = await app.runContained((Todo t) => t, null, null, c); + expect(r, c); + }); + test("singleton in route", () async { validateTodoSingleton(await client.get("$url/errands")); });