diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml
index ec70caa9..db6079ec 100644
--- a/.idea/libraries/Dart_Packages.xml
+++ b/.idea/libraries/Dart_Packages.xml
@@ -12,7 +12,7 @@
-
+
@@ -454,7 +454,7 @@
-
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index aa5d08f2..6c8be27b 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -2,13 +2,17 @@
+
-
-
+
+
+
+
+
-
-
+
+
@@ -34,8 +38,8 @@
-
-
+
+
@@ -43,23 +47,32 @@
-
-
+
+
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
@@ -67,8 +80,8 @@
-
-
+
+
@@ -76,51 +89,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -133,15 +101,6 @@
- super
- close()
- DEFUNC
- const
- dart2_constant/convert.dart
- dart2_constant/io.dart
- package:dart:convert
- package:dart:io
- deprecated
parse
io
io.
@@ -163,6 +122,15 @@
add(
close(
end()
+ stop
+ sto
+ sopw
+ stopw
+ release
+ handleRe
+ mirrors
+ get container
+ Parameter
FutureOr
@@ -218,8 +186,6 @@
@@ -278,12 +246,18 @@
true
DEFINITION_ORDER
+
+
+
+
+
+
-
-
+
+
@@ -328,6 +302,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -376,7 +362,7 @@
-
+
@@ -676,14 +662,7 @@
-
-
-
- 1534547008912
-
-
-
- 1534547008913
+
1534547132671
@@ -1021,13 +1000,17 @@
1534815933898
-
+
+ 1534816646962
+
+
+
+ 1534816646962
+
+
-
-
-
@@ -1055,9 +1038,12 @@
+
+
+
-
+
@@ -1069,7 +1055,7 @@
-
+
@@ -1095,7 +1081,7 @@
-
+
@@ -1120,7 +1106,6 @@
-
@@ -1145,7 +1130,8 @@
-
+
+
@@ -1153,53 +1139,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1245,13 +1184,6 @@
-
-
-
-
-
-
-
@@ -1294,20 +1226,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1336,33 +1254,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1370,13 +1261,6 @@
-
-
-
-
-
-
-
@@ -1391,13 +1275,6 @@
-
-
-
-
-
-
-
@@ -1430,13 +1307,6 @@
-
-
-
-
-
-
-
@@ -1454,12 +1324,22 @@
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
@@ -1478,53 +1358,181 @@
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example/main.dart b/example/main.dart
index 3a97ef61..d52378fc 100644
--- a/example/main.dart
+++ b/example/main.dart
@@ -24,7 +24,9 @@ main() async {
'/greet/:name',
(req, res) {
var name = req.params['name'];
- res.write('Hello, $name!');
+ res
+ ..write('Hello, $name!')
+ ..close();
},
);
diff --git a/lib/src/core/hooked_service.dart b/lib/src/core/hooked_service.dart
index 0bca22d0..7ef14e78 100644
--- a/lib/src/core/hooked_service.dart
+++ b/lib/src/core/hooked_service.dart
@@ -6,6 +6,7 @@ import 'request_context.dart';
import 'response_context.dart';
import 'routable.dart';
import 'metadata.dart';
+import 'server.dart';
import 'service.dart';
/// Wraps another service in a service that broadcasts events on actions.
@@ -85,8 +86,8 @@ class HookedService extends Service {
}
/// Adds hooks to this instance.
- void addHooks() {
- Hooks hooks = getAnnotation(inner, Hooks);
+ void addHooks(Angel app) {
+ Hooks hooks = getAnnotation(inner, Hooks, app.container.reflector);
List before = [], after = [];
if (hooks != null) {
@@ -96,7 +97,7 @@ class HookedService extends Service {
void applyListeners(Function fn, HookedServiceEventDispatcher dispatcher,
[bool isAfter]) {
- Hooks hooks = getAnnotation(fn, Hooks);
+ Hooks hooks = getAnnotation(fn, Hooks, app.container.reflector);
final listeners = []
..addAll(isAfter == true ? after : before);
diff --git a/lib/src/core/injection.dart b/lib/src/core/injection.dart
index e87c485c..6e56635a 100644
--- a/lib/src/core/injection.dart
+++ b/lib/src/core/injection.dart
@@ -5,10 +5,15 @@ const List _primitiveTypes = [String, int, num, double, Null];
/// Shortcut for calling [preInject], and then [handleContained].
///
/// Use this to instantly create a request handler for a DI-enabled method.
+///
+/// Calling [ioc] also auto-serializes the result of a [handler].
RequestHandler ioc(Function handler, {Iterable optional: const []}) {
var injection = preInject(handler);
injection.optional.addAll(optional ?? []);
- return handleContained(handler, injection);
+ var contained = handleContained(handler, injection);
+ return (req, res) {
+ return req.app.executeHandler(contained, req, res);
+ };
}
resolveInjection(requirement, InjectionRequest injection, RequestContext req,
diff --git a/lib/src/core/routable.dart b/lib/src/core/routable.dart
index b809c873..29b7c33d 100644
--- a/lib/src/core/routable.dart
+++ b/lib/src/core/routable.dart
@@ -2,6 +2,7 @@ library angel_framework.http.routable;
import 'dart:async';
+import 'package:angel_container/angel_container.dart';
import 'package:angel_route/angel_route.dart';
import '../util.dart';
@@ -45,7 +46,14 @@ class Routable extends Router {
final Map _services = {};
final Map configuration = {};
- Routable() : super();
+ final Container _container;
+
+ Routable([Reflector reflector])
+ : _container = reflector == null ? null : new Container(reflector),
+ super();
+
+ /// A [Container] used to inject dependencies.
+ Container get container => _container;
void close() {
_services.clear();
@@ -75,7 +83,8 @@ class Routable extends Router {
{Iterable middleware: const []}) {
final handlers = [];
// Merge @Middleware declaration, if any
- Middleware middlewareDeclaration = getAnnotation(handler, Middleware);
+ Middleware middlewareDeclaration =
+ getAnnotation(handler, Middleware, _container?.reflector);
if (middlewareDeclaration != null) {
handlers.addAll(middlewareDeclaration.handlers);
}
diff --git a/lib/src/core/server.dart b/lib/src/core/server.dart
index 42c5535f..6cd1b66b 100644
--- a/lib/src/core/server.dart
+++ b/lib/src/core/server.dart
@@ -104,8 +104,6 @@ class Angel extends Routable {
/// These will only not run if a response's `willCloseItself` is set to `true`.
final List responseFinalizers = [];
- Container _container;
-
/// A [Map] of application-specific data that can be accessed by any
/// piece of code that can see this [Angel] instance.
///
@@ -122,9 +120,6 @@ class Angel extends Routable {
/// on requests. `false` by default.
bool keepRawRequestBuffers = false;
- /// A [Container] used to inject dependencies.
- Container get container => _container;
-
/// A function that renders views.
///
/// Called by [ResponseContext]@`render`.
@@ -199,7 +194,6 @@ class Angel extends Routable {
});
super.close();
- _container = null;
viewGenerator = noViewEngineConfigured;
_preContained.clear();
handlerCache.clear();
@@ -371,8 +365,8 @@ class Angel extends Routable {
this.allowMethodOverrides: true,
this.keepRawRequestBuffers: false,
this.serializer,
- this.viewGenerator}) {
- _container = new Container(reflector);
+ this.viewGenerator})
+ : super(reflector) {
bootstrapContainer();
viewGenerator ??= noViewEngineConfigured;
serializer ??= json.encode;
diff --git a/lib/src/core/service.dart b/lib/src/core/service.dart
index cdba7ecc..e157da8f 100644
--- a/lib/src/core/service.dart
+++ b/lib/src/core/service.dart
@@ -154,11 +154,11 @@ class Service extends Routable {
var handlers = new List.from(handlerss);
// Add global middleware if declared on the instance itself
- Middleware before = getAnnotation(service, Middleware);
+ Middleware before = getAnnotation(service, Middleware, app.container.reflector);
if (before != null) handlers.addAll(before.handlers);
- Middleware indexMiddleware = getAnnotation(service.index, Middleware);
+ Middleware indexMiddleware = getAnnotation(service.index, Middleware, app.container.reflector);
get('/', (req, res) {
return req.parseQuery().then((query) {
return this.index(mergeMap([
@@ -172,7 +172,7 @@ class Service extends Routable {
..addAll(handlers)
..addAll((indexMiddleware == null) ? [] : indexMiddleware.handlers));
- Middleware createMiddleware = getAnnotation(service.create, Middleware);
+ Middleware createMiddleware = getAnnotation(service.create, Middleware, app.container.reflector);
post('/', (req, ResponseContext res) {
return req.parseQuery().then((query) {
return req.parseBody().then((body) {
@@ -196,7 +196,7 @@ class Service extends Routable {
..addAll(
(createMiddleware == null) ? [] : createMiddleware.handlers));
- Middleware readMiddleware = getAnnotation(service.read, Middleware);
+ Middleware readMiddleware = getAnnotation(service.read, Middleware, app.container.reflector);
get('/:id', (req, res) {
return req.parseQuery().then((query) {
@@ -213,7 +213,7 @@ class Service extends Routable {
..addAll(handlers)
..addAll((readMiddleware == null) ? [] : readMiddleware.handlers));
- Middleware modifyMiddleware = getAnnotation(service.modify, Middleware);
+ Middleware modifyMiddleware = getAnnotation(service.modify, Middleware, app.container.reflector);
patch(
'/:id',
(req, res) => req.parseBody().then((body) {
@@ -233,7 +233,7 @@ class Service extends Routable {
..addAll(
(modifyMiddleware == null) ? [] : modifyMiddleware.handlers));
- Middleware updateMiddleware = getAnnotation(service.update, Middleware);
+ Middleware updateMiddleware = getAnnotation(service.update, Middleware, app.container.reflector);
post(
'/:id',
(req, res) => req.parseBody().then((body) {
@@ -271,7 +271,7 @@ class Service extends Routable {
..addAll(
(updateMiddleware == null) ? [] : updateMiddleware.handlers));
- Middleware removeMiddleware = getAnnotation(service.remove, Middleware);
+ Middleware removeMiddleware = getAnnotation(service.remove, Middleware, app.container.reflector);
delete('/', (req, res) {
return req.parseQuery().then((query) {
return this.remove(
diff --git a/lib/src/http/angel_http.dart b/lib/src/http/angel_http.dart
index 4c3e4e29..d2b1c950 100644
--- a/lib/src/http/angel_http.dart
+++ b/lib/src/http/angel_http.dart
@@ -141,18 +141,17 @@ class AngelHttp {
var pipeline = tuple.item1;
- Future Function() runPipeline;
+ Future Function() runPipeline;
for (var handler in pipeline) {
if (handler == null) break;
if (runPipeline == null)
- runPipeline = () => app.executeHandler(handler, req, res);
+ runPipeline = () => Future.sync(() => handler(req, res));
else {
var current = runPipeline;
- runPipeline = () => current().then((result) => !result
- ? new Future.value(result)
- : app.executeHandler(handler, req, res));
+ runPipeline = () => current().then((result) =>
+ !res.isOpen ? new Future.value(result) : handler(req, res));
}
}
diff --git a/lib/src/util.dart b/lib/src/util.dart
index 435ad4e9..077551c2 100644
--- a/lib/src/util.dart
+++ b/lib/src/util.dart
@@ -1,26 +1,26 @@
-import 'dart:async';
-import 'dart:mirrors';
+import 'package:angel_container/angel_container.dart';
final RegExp straySlashes = new RegExp(r'(^/+)|(/+$)');
-matchingAnnotation(List metadata, Type T) {
- for (InstanceMirror metaDatum in metadata) {
- if (metaDatum.hasReflectee) {
- var reflectee = metaDatum.reflectee;
- if (reflectee.runtimeType == T) {
- return reflectee;
- }
+matchingAnnotation(List metadata, Type T) {
+ for (ReflectedInstance metaDatum in metadata) {
+ if (metaDatum.type == T) {
+ return metaDatum.reflectee;
}
}
return null;
}
-getAnnotation(obj, Type T) {
- if (obj is Function || obj is Future) {
- MethodMirror methodMirror = (reflect(obj) as ClosureMirror).function;
- return matchingAnnotation(methodMirror.metadata, T);
+getAnnotation(obj, Type T, Reflector reflector) {
+ if (reflector == null) {
+ return null;
} else {
- ClassMirror classMirror = reflectClass(obj.runtimeType as Type);
- return matchingAnnotation(classMirror.metadata, T);
+ if (obj is Function) {
+ var methodMirror = reflector.reflectFunction(obj);
+ return matchingAnnotation(methodMirror.annotations, T);
+ } else {
+ var classMirror = reflector.reflectClass(obj.runtimeType as Type);
+ return matchingAnnotation(classMirror.annotations, T);
+ }
}
}
diff --git a/test/hooked_test.dart b/test/hooked_test.dart
index 8c9ce923..97fc4980 100644
--- a/test/hooked_test.dart
+++ b/test/hooked_test.dart
@@ -98,7 +98,7 @@ main() {
});
test('metadata', () async {
- final service = new HookedService(new IncrementService())..addHooks();
+ final service = new HookedService(new IncrementService())..addHooks(app);
expect(service.inner, isNot(const IsInstanceOf()));
IncrementService.TIMES = 0;
await service.index();