2.0.0-rc.4 (async injections)
This commit is contained in:
parent
106a5683dd
commit
09ff68f5ad
4 changed files with 54 additions and 12 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
# 2.0.0-rc.4
|
||||||
|
* Support resolution of asynchronous injections in controllers and `ioc`.
|
||||||
|
* Inject `RequestContext` and `ResponseContext` into requests.
|
||||||
|
|
||||||
# 2.0.0-rc.3
|
# 2.0.0-rc.3
|
||||||
* `MapService.modify` was not actually modifying items.
|
* `MapService.modify` was not actually modifying items.
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,8 @@ abstract class Driver<
|
||||||
req.params.addAll(tuple.item2);
|
req.params.addAll(tuple.item2);
|
||||||
|
|
||||||
req.container
|
req.container
|
||||||
|
..registerSingleton<RequestContext>(req)
|
||||||
|
..registerSingleton<ResponseContext>(res)
|
||||||
..registerSingleton<MiddlewarePipeline>(tuple.item4)
|
..registerSingleton<MiddlewarePipeline>(tuple.item4)
|
||||||
..registerSingleton<MiddlewarePipeline<RequestHandler>>(line)
|
..registerSingleton<MiddlewarePipeline<RequestHandler>>(line)
|
||||||
..registerSingleton<MiddlewarePipelineIterator>(it)
|
..registerSingleton<MiddlewarePipelineIterator>(it)
|
||||||
|
|
|
@ -24,7 +24,7 @@ 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]) {
|
[Container container]) async {
|
||||||
var propFromApp;
|
var propFromApp;
|
||||||
container ??= req?.container ?? res?.app?.container;
|
container ??= req?.container ?? res?.app?.container;
|
||||||
|
|
||||||
|
@ -60,12 +60,19 @@ 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(
|
return await resolveInjection(
|
||||||
key, injection, req, res, throwOnUnresolved, container);
|
key, injection, req, res, throwOnUnresolved, container);
|
||||||
} else
|
} else
|
||||||
return resolveInjection(
|
return await resolveInjection(
|
||||||
type, injection, req, res, throwOnUnresolved, container);
|
type, injection, req, res, throwOnUnresolved, container);
|
||||||
} else if (requirement is Type && requirement != dynamic) {
|
} else if (requirement is Type && requirement != dynamic) {
|
||||||
|
try {
|
||||||
|
var futureType = container.reflector.reflectFutureOf(requirement);
|
||||||
|
return await container.make(futureType.reflectedType);
|
||||||
|
} on UnsupportedError {
|
||||||
|
// Ignore this; it just means that the reflector doesn't support futures.
|
||||||
|
}
|
||||||
|
|
||||||
return container.make(requirement);
|
return container.make(requirement);
|
||||||
} else if (throwOnUnresolved) {
|
} else if (throwOnUnresolved) {
|
||||||
throw new ArgumentError(
|
throw new ArgumentError(
|
||||||
|
@ -86,7 +93,7 @@ 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]) {
|
[Container container]) {
|
||||||
return (RequestContext req, ResponseContext res) {
|
return (RequestContext req, ResponseContext res) async {
|
||||||
if (injection.parameters.isNotEmpty &&
|
if (injection.parameters.isNotEmpty &&
|
||||||
injection.parameters.values.any((p) => p.match != null) &&
|
injection.parameters.values.any((p) => p.match != null) &&
|
||||||
!suitableForInjection(req, res, injection))
|
!suitableForInjection(req, res, injection))
|
||||||
|
@ -95,14 +102,16 @@ RequestHandler handleContained(Function handler, InjectionRequest injection,
|
||||||
List args = [];
|
List args = [];
|
||||||
|
|
||||||
Map<Symbol, dynamic> named = {};
|
Map<Symbol, dynamic> named = {};
|
||||||
args.addAll(injection.required
|
|
||||||
.map((r) => resolveInjection(r, injection, req, res, true, container)));
|
|
||||||
|
|
||||||
injection.named.forEach((k, v) {
|
for (var r in injection.required) {
|
||||||
var name = new Symbol(k);
|
args.add(await resolveInjection(r, injection, req, res, true, container));
|
||||||
named[name] =
|
}
|
||||||
resolveInjection([k, v], injection, req, res, false, container);
|
|
||||||
});
|
for (var entry in injection.named.entries) {
|
||||||
|
var name = new Symbol(entry.key);
|
||||||
|
named[name] = await resolveInjection(
|
||||||
|
[entry.key, entry.value], injection, req, res, false, container);
|
||||||
|
}
|
||||||
|
|
||||||
return Function.apply(handler, args, named);
|
return Function.apply(handler, args, named);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:angel_container/angel_container.dart';
|
import 'package:angel_container/angel_container.dart';
|
||||||
import 'package:angel_framework/http.dart';
|
import 'package:angel_framework/http.dart';
|
||||||
import 'package:angel_container/mirrors.dart';
|
import 'package:angel_container/mirrors.dart';
|
||||||
|
@ -26,12 +26,18 @@ main() {
|
||||||
|
|
||||||
// Inject some todos
|
// Inject some todos
|
||||||
app.container.registerSingleton(new Todo(text: TEXT, over: OVER));
|
app.container.registerSingleton(new Todo(text: TEXT, over: OVER));
|
||||||
|
app.container.registerFactory<Future<Foo>>((container) async {
|
||||||
|
var req = container.make<RequestContext>();
|
||||||
|
var text = await req.body.transform(utf8.decoder).join();
|
||||||
|
return Foo(text);
|
||||||
|
});
|
||||||
|
|
||||||
app.get("/errands", ioc((Todo singleton) => singleton));
|
app.get("/errands", ioc((Todo singleton) => singleton));
|
||||||
app.get(
|
app.get(
|
||||||
"/errands3",
|
"/errands3",
|
||||||
ioc(({Errand singleton, Todo foo, RequestContext req}) =>
|
ioc(({Errand singleton, Todo foo, RequestContext req}) =>
|
||||||
singleton.text));
|
singleton.text));
|
||||||
|
app.post('/async', ioc((Foo foo) => {'baz': foo.bar}));
|
||||||
await app.configure(new SingletonController().configureServer);
|
await app.configure(new SingletonController().configureServer);
|
||||||
await app.configure(new ErrandController().configureServer);
|
await app.configure(new ErrandController().configureServer);
|
||||||
|
|
||||||
|
@ -82,6 +88,16 @@ main() {
|
||||||
var text = await json.decode(response.body) as String;
|
var text = await json.decode(response.body) as String;
|
||||||
expect(text, equals(TEXT));
|
expect(text, equals(TEXT));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('resolve from future in controller', () async {
|
||||||
|
var response = await client.post('$url/errands4/async', body: 'hey');
|
||||||
|
expect(response.body, json.encode({'bar': 'hey'}));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('resolve from future in route', () async {
|
||||||
|
var response = await client.post('$url/async', body: 'yes');
|
||||||
|
expect(response.body, json.encode({'baz': 'yes'}));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateTodoSingleton(response) {
|
void validateTodoSingleton(response) {
|
||||||
|
@ -103,6 +119,17 @@ class ErrandController extends Controller {
|
||||||
errand(Errand errand) {
|
errand(Errand errand) {
|
||||||
return errand.text;
|
return errand.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Expose('/async', method: 'POST')
|
||||||
|
asyncResolve(Foo foo) {
|
||||||
|
return {'bar': foo.bar};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
final String bar;
|
||||||
|
|
||||||
|
Foo(this.bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Errand {
|
class Errand {
|
||||||
|
|
Loading…
Reference in a new issue