angel3_container 10.0.0
angel3_container: ^10.0.0 copied to clipboard
Angel3 hierarchical DI container, and pluggable backends for reflection.
Angel3 Container #
A better IoC container for Angel3, ultimately allowing Angel3 to be used with or without dart:mirrors package.
Installation #
In your pubspec.yaml:
dependencies:
angel3_container: ^10.0.0
Usage #
Register what to inject, then make it:
import 'package:angel3_container/angel3_container.dart';
void main() async {
// Everything here is registered, so it needs no reflection.
var container = Container(const EmptyReflector());
// Register a singleton.
container.registerSingleton<Engine>(Engine(40));
// Register a factory that creates a truck.
container.registerFactory<Truck>((container) {
return Truck(container.make<Engine>());
});
// Use `make` to create an instance.
container.make<Truck>().drive(); // Vroom! I have 40 horsepower.
// You can also resolve injections asynchronously.
container.registerFactory<Future<int>>((_) async => 24);
print(await container.makeAsync<int>()); // 24
// A child container can override a factory of its parent.
var child = container.createChild()
..registerFactory<Truck>((_) => Truck(Engine(5666)));
child.make<Truck>().drive(); // Vroom! I have 5666 horsepower.
}
class Engine {
final int horsePower;
Engine(this.horsePower);
}
class Truck {
final Engine engine;
Truck(this.engine);
void drive() => print('Vroom! I have ${engine.horsePower} horsepower.');
}
Reflectors #
This package does not use dart:mirrors. Pick a Reflector backend:
MirrorsReflector, fromangel3_container_mirrors, for apps run on the Dart VMStaticReflector.combine([...]), from this package, with the data thatangel3_container_generatorgenerates for@injectableclasses, for apps compiled ahead of timeEmptyReflectororThrowingReflector, from this package, when everything is registered explicitly
Before 10.0.0, MirrorsReflector was imported from package:angel3_container/mirrors.dart. Add angel3_container_mirrors to your dependencies and import package:angel3_container_mirrors/angel3_container_mirrors.dart instead.
With Angel3 #
With a reflector, the app constructs controllers and injects their dependencies:
import 'package:angel3_container_mirrors/angel3_container_mirrors.dart';
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart';
@Expose('/sales', middleware: [process1])
class SalesController extends Controller {
@Expose('/', middleware: [process2])
Future<String> route1(RequestContext req, ResponseContext res) async {
return "Sales route";
}
}
bool process1(RequestContext req, ResponseContext res) {
res.write('Hello, ');
return true;
}
bool process2(RequestContext req, ResponseContext res) {
res.write('From Sales, ');
return true;
}
void main() async {
// Using Mirror Reflector
var app = Angel(reflector: MirrorsReflector());
// Sales Controller
app.container.registerSingleton<SalesController>(SalesController());
await app.mountController<SalesController>();
var http = AngelHttp(app);
var server = await http.startServer('localhost', 3000);
print("Angel3 server listening at ${http.uri}");
}
Migrating from 9.x to 10.0.0 #
The breaking changes of each release are listed in the CHANGELOG. Those of 10.0.0 that may need changes in an app:
MirrorsReflector:package:angel3_container/mirrors.dartis removed. Addangel3_container_mirrorsto your dependencies, and importpackage:angel3_container_mirrors/angel3_container_mirrors.dartinstead.- Optional parameters:
Container.makeleaves out an optional positional parameter whose type is not registered, so it isnullor keeps its default, instead of constructing it by reflection. Register the types you want injected. StaticReflectedInstance.getFieldthrows aReflectionExceptionfor a name that is no member, instead of returningnull, and aStaticMemberReaderreturnsnoStaticMemberfor it.