Custom container in handleContained
This commit is contained in:
parent
b1d685797e
commit
0d64e101f4
5 changed files with 33 additions and 15 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
# 2.0.0-alpha.6
|
||||||
|
* Allow passing a custom `Container` to `handleContained` and co.
|
||||||
|
|
||||||
# 2.0.0-alpha.5
|
# 2.0.0-alpha.5
|
||||||
* `MapService` methods now explicitly return `Map<String, dynamic>`.
|
* `MapService` methods now explicitly return `Map<String, dynamic>`.
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,9 @@ RequestHandler ioc(Function handler, {Iterable<String> optional: const []}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveInjection(requirement, InjectionRequest injection, RequestContext req,
|
resolveInjection(requirement, InjectionRequest injection, RequestContext req,
|
||||||
ResponseContext res, bool throwOnUnresolved) {
|
ResponseContext res, bool throwOnUnresolved, [Container container]) {
|
||||||
var propFromApp;
|
var propFromApp;
|
||||||
|
container ??= req?.container ?? res?.app?.container;
|
||||||
|
|
||||||
if (requirement == RequestContext) {
|
if (requirement == RequestContext) {
|
||||||
return req;
|
return req;
|
||||||
|
@ -56,11 +57,11 @@ resolveInjection(requirement, InjectionRequest injection, RequestContext req,
|
||||||
if (req.params.containsKey(key) ||
|
if (req.params.containsKey(key) ||
|
||||||
req.app.configuration.containsKey(key) ||
|
req.app.configuration.containsKey(key) ||
|
||||||
_primitiveTypes.contains(type)) {
|
_primitiveTypes.contains(type)) {
|
||||||
return resolveInjection(key, injection, req, res, throwOnUnresolved);
|
return resolveInjection(key, injection, req, res, throwOnUnresolved, container);
|
||||||
} else
|
} else
|
||||||
return resolveInjection(type, injection, req, res, throwOnUnresolved);
|
return resolveInjection(type, injection, req, res, throwOnUnresolved, container);
|
||||||
} else if (requirement is Type && requirement != dynamic) {
|
} else if (requirement is Type && requirement != dynamic) {
|
||||||
return req.app.container.make(requirement);
|
return container.make(requirement);
|
||||||
} else if (throwOnUnresolved) {
|
} else if (throwOnUnresolved) {
|
||||||
throw new ArgumentError(
|
throw new ArgumentError(
|
||||||
'$requirement cannot be injected into a request handler.');
|
'$requirement cannot be injected into a request handler.');
|
||||||
|
@ -78,7 +79,8 @@ bool suitableForInjection(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles a request with a DI-enabled handler.
|
/// 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) {
|
return (RequestContext req, ResponseContext res) {
|
||||||
if (injection.parameters.isNotEmpty &&
|
if (injection.parameters.isNotEmpty &&
|
||||||
injection.parameters.values.any((p) => p.match != null) &&
|
injection.parameters.values.any((p) => p.match != null) &&
|
||||||
|
@ -89,11 +91,12 @@ RequestHandler handleContained(Function handler, InjectionRequest injection) {
|
||||||
|
|
||||||
Map<Symbol, dynamic> named = {};
|
Map<Symbol, dynamic> named = {};
|
||||||
args.addAll(injection.required
|
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) {
|
injection.named.forEach((k, v) {
|
||||||
var name = new Symbol(k);
|
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);
|
return Function.apply(handler, args, named);
|
||||||
|
|
|
@ -306,24 +306,26 @@ class Angel extends Routable {
|
||||||
/// Run a function after injecting from service container.
|
/// Run a function after injecting from service container.
|
||||||
/// If this function has been reflected before, then
|
/// If this function has been reflected before, then
|
||||||
/// the execution will be faster, as the injection requirements were stored beforehand.
|
/// the execution will be faster, as the injection requirements were stored beforehand.
|
||||||
Future runContained(
|
Future runContained(Function handler, RequestContext req, ResponseContext res,
|
||||||
Function handler, RequestContext req, ResponseContext res) {
|
[Container container]) {
|
||||||
return new Future.sync(() {
|
return new Future.sync(() {
|
||||||
if (_preContained.containsKey(handler)) {
|
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].
|
/// Runs with DI, and *always* reflects. Prefer [runContained].
|
||||||
Future runReflected(
|
Future runReflected(Function handler, RequestContext req, ResponseContext res,
|
||||||
Function handler, RequestContext req, ResponseContext res) {
|
[Container container]) {
|
||||||
var h = handleContained(
|
var h = handleContained(
|
||||||
handler,
|
handler,
|
||||||
_preContained[handler] =
|
_preContained[handler] =
|
||||||
preInject(handler, req.app.container.reflector));
|
preInject(handler, req.app.container.reflector),
|
||||||
|
container);
|
||||||
return new Future.sync(() => h(req, res));
|
return new Future.sync(() => h(req, res));
|
||||||
// return closureMirror.apply(args).reflectee;
|
// return closureMirror.apply(args).reflectee;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel_framework
|
name: angel_framework
|
||||||
version: 2.0.0-alpha.5
|
version: 2.0.0-alpha.6
|
||||||
description: >
|
description: >
|
||||||
A high-powered HTTP server with DI, routing and more.
|
A high-powered HTTP server with DI, routing and more.
|
||||||
When combined with the other packages in the Angel ecosystem, this
|
When combined with the other packages in the Angel ecosystem, this
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:angel_container/angel_container.dart';
|
||||||
import 'package:angel_container/mirrors.dart';
|
import 'package:angel_container/mirrors.dart';
|
||||||
import 'package:angel_framework/angel_framework.dart';
|
import 'package:angel_framework/angel_framework.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
@ -44,6 +45,15 @@ main() {
|
||||||
await server.close(force: true);
|
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 {
|
test("singleton in route", () async {
|
||||||
validateTodoSingleton(await client.get("$url/errands"));
|
validateTodoSingleton(await client.get("$url/errands"));
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue