A Dependency Injection package taken from angular DI.
Create one of the examples shown below
Create an Injector by using annotation @GenerateInjector
and pass the
List of types, then the generator will create the respective injector.
@GenerateInjector([Engine, Car])
final injector = injector$Injector();
Full code:
@GenerateInjector([Engine, Car])
final injector = injector$Injector();
In this case you can specify the token corresponding to the dependency that will be injected. For example:
library example.inject;
import 'package:ng_di/ng_di.dart';
part 'inject.ng_di.g.dart';
const v4_engine_token = OpaqueToken<String>('v4_engine_token');
const v8_engine_token = OpaqueToken<String>('v8_engine_token');
const truck_token = OpaqueToken<String>('truck_token');
class Engine {
String name;
Engine([@Inject(v4_engine_token) this.name]);
}
class Car {
final Engine engine;
Car(this.engine);
}
_truckFactory(String name) => Car(Engine(name));
@GenerateInjector([
Provider(v4_engine_token, useValue: 'v4-engine'),
Provider(v8_engine_token, useValue: 'v8-engine'),
Engine,
Car,
Provider(truck_token, useFactory: _truckFactory, deps: [v8_engine_token])
])
final injector = injector$Injector();
main() {
print('Car.engine: ${injector.get(Car).engine.name}');
assert(injector.get(Car).engine.name == 'v4-engine');
print('truck.engine: ${injector.get(truck_token).engine.name}');
assert(injector.get(truck_token).engine.name == 'v8-engine');
}
In this case we can mark dependencies as optional, so if the value is not injected then a null value is passed. For example:
library example.optional;
import 'package:ng_di/ng_di.dart';
part 'optional.ng_di.g.dart';
@injectable
class Engine {
}
@injectable
class Car {
final Engine engine;
Car(@optional this.engine);
}
class Truck {
final Engine engine;
Truck([this.engine]);
}
class Boat {
final Engine engine;
Boat({this.engine});
}
@GenerateInjector([Car, Truck, Boat])
final injector = injector$Injector();
main() {
print('Carg.engine: ${injector.get(Car).engine}');
print('Truck.engine: ${injector.get(Truck).engine}');
print('Boat.engine: ${injector.get(Boat).engine}');
}
In this case we can mark dependencies as self, so the injector should retrieve a dependency only from itself. For example:
library example.self;
import 'package:ng_di/ng_di.dart';
part 'self.ng_di.g.dart';
@Injectable()
class Engine {
String name;
Engine();
}
@Injectable()
class Car {
final Engine engine;
Car(@self this.engine);
}
@GenerateInjector([Engine, Car])
final injector = injector$Injector();
@GenerateInjector([Engine])
final parentInjector = parentInjector$Injector();
@GenerateInjector([Car])
final childInjector = childInjector$Injector(parentInjector);
main() {
assert(injector.get(Car).engine.name == null);
print('Car.engine: ${injector.get(Car).engine.name}');
try {
print('Car.engine: ${childInjector.get(Car).engine.name == null}');
} catch (e) {
print('error: $e');
}
}
In this case we can mark dependencies as optional, so the dependency resolution should start from the parent injector. For example:
library example.skip_self;
import 'package:ng_di/ng_di.dart';
part 'skip_self.ng_di.g.dart';
@injectable
class Engine {
String name;
Engine();
}
@injectable
class Car {
final Engine engine;
Car(@skipSelf this.engine);
}
@GenerateInjector([Engine, Car])
final injector = injector$Injector();
@GenerateInjector([Engine])
final parentInjector = parentInjector$Injector();
@GenerateInjector([Car])
final childInjector = childInjector$Injector(parentInjector);
main() {
try {
print('Car.engine: ${injector.get(Car).engine.name == null}');
} catch (e) {
print('error: $e');
}
assert(childInjector.get(Car).engine.name == null);
print('Car.engine: ${childInjector.get(Car).engine.name}');
}