dice 1.6.3 dice: ^1.6.3 copied to clipboard
Lightweight dependency injection framework for Dart.
Dice #
Lightweight dependency injection framework for Dart.
Getting Started #
Dice consists of two parts.
- Modules containing your class registrations.
- Injectors that uses the Module to inject instances into your code.
The following example should get you startd:
1. Add the Dice to your pubspec.yaml and run pub install
dependencies:
dice: any
2. Create some classes and interfaces to inject
class BillingServiceImpl implements BillingService {
@inject
CreditProcessor _processor;
Receipt chargeOrder(Order order, CreditCard creditCard) {
if(!_processor.validate(creditCard)) {
throw new ArgumentError("payment method not accepted");
}
// :
}
}
3. Register types and classes in a module
class ExampleModule extends Module {
configure() {
// register [CreditProcessor] as a singleton
register(CreditProcessor).toInstance(new CreditProcessorImpl());
// register [BillingService] so a new version is created each time its requested
register(BillingService).toType(BillingServiceImpl);
}
}
4. Run it
import "package:dice/dice.dart";
main() {
var injector = new Injector(new ExampleModule());
var billingService = injector.getInstance(BillingService);
var creditCard = new CreditCard("VISA");
var order = new Order("Dart: Up and Running");
billingService.chargeOrder(order, creditCard);
}
for more information see the full example here.
Dependency Injection with Dice #
You can use the @inject annotation to mark objects and functions for injection the following ways:
- Injection of public and private fields (object/instance variables)
class MyOtherClass {
@inject
SomeClass field;
@inject
SomeOtherClass _privateField;
}
- Injection of constructor parameters
class MyClass {
@inject
MyClass(this.field);
MyOtherClass field;
}
- Injection of public and private setters
class SomeClass {
@inject
set value(SomeOtherClass val) => _privateValue = val;
@inject
set _value(SomeOtherClass val) => _anotherPrivateValue = val;
SomeOtherClass _privateValue, _anotherPrivateValue;
}
The injected objects are configured ether by extending the Module class and using one its register functions or directly on the Injector.
- register type MyType to existing object (singleton injections)
register(MyType).toInstance(object)
- register type MyType.
register(MyType)
- register interface MyType to a class implementing it.
register(MyType).toType(MyTypeImpl)
- register a typedef to a function matching it.
register(MyTypedef).toFunction(function)
- register MyType to function that can build instances of it
register(MyType).toBuilder(() => new MyType())
Named Injections #
Dice supports named injections by using the @Named annotation. Currently this annotation works everywhere the @inject annotation works, except for constructors.
class MyClass {
@inject
@Named('my-special-implementation')
SomeClass _someClass;
}
The configuration is as before except you now provide an additional name paramater.
register(MyType, "my-name").toType(MyTypeImpl)
Advanced Features #
- Get instances directly Instead of using the @inject annotation to resolve injections you can use the injectors getInstance method.
MyClass instance = injector.getInstance(MyClass);
- Get named instances directly Instead of using the @Named annotation to resolve named injections you can use the injectors getInstance method with its name parameter.
MyType instance = injector.getInstance(MyType, "my-name");
- To register and resole configuration values You can use named registrations to inject configuration values into your application.
class TestModule extends Module {
configure() {
register(String, "web-service-host").toInstace("http://test-service.name");
}
}
// application code
String get webServiceHost => injector.getInstance(String, "web-service-host");
- Registering dependencies at runtime You can register dependencies at runtime directly on the Injector.
injector.register(User).toInstance(user);
var user = injector.getInstance(User);
- Unregistering dependencies at runtime You can unregister dependencies at runtime using the unregister method on the Injector.
injector.unregister(User);
- Using multiple modules You can compose modules using the Injector.fromModules constructor.
class MyModule extends Module {
configure() {
register(MyClass).toType(MyClass);
}
}
class YourModule extends Module {
configure() {
register(YourClass).toType(YourClass);
}
}
var injector = new Injector.fromModules([new MyModule(), new YourModule()]);
var myClass = injector.getInstance(MyClass);
var yourClass = injector.getInstance(YourClass);
- Joining injectors You can join multiple injector instances to one using the Injector.fromInjectors constructor.
var myInjector = new Injector();
myInjector.register(MyClass).toType(MyClass);
var yourInjector = new Injector();
yourInjector.register(YourClass).toType(YourClass);
var injector = new Injector.fromInjectors([myInjector, yourInjector]);
var myClass = injector.getInstance(MyClass);
var yourClass = injector.getInstance(YourClass);