dryice 2.0.15

  • README.md
  • CHANGELOG.md
  • Installing
  • Versions
  • 29

DryIce (built mirrors / reflectable)

Lightweight dependency injection framework for Dart.

Built mirrors / reflectable

This branch is in a very early stage and works only with Dart 2.x but if you want to try it:

git clone -b reflectable git@github.com:MikeMitterer/dryice.git reflectable
cd reflectable
pub update
dart tool/build.dart test/*_test.dart
pub run test test/dice_test.dart
pub run test test/dice_test.dart -p chrome

Getting Started

DryIce 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 started:

1. Add DryIce to your pubspec.yaml and run pub install

dependencies:
   dryice: any

2. Create some classes and interfaces to inject

@injectable
abstract class BillingService {
    Receipt chargeOrder(Order order, CreditCard creditCard);
}

@injectable
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 {

  @override
  configure() {
    // register [CreditProcessor] as a singleton
    bind(CreditProcessor).to(CreditProcessorImpl).asSingleton();

    // register [BillingService] so a new version is created each time its requested
    bind(BillingService).toType(BillingServiceImpl);
  }
}

4. Run it

import "package:dryice/dryice.dart";
main() {
	final injector = new Injector(new ExampleModule());
	final billingService = injector.getInstance(BillingService);
	final creditCard = new CreditCard("VISA");
	final order = new Order("Dart: Up and Running");
	billingService.chargeOrder(order, creditCard);
}

for more information see the full example here.

Dependency Injection with DryIce

You can use the @injectable annotation to mark classes as injectable, use @inject annotation to mark objects, functions and constructors for injection the following ways: (It is not necessary to mark a default constructor with @inject - only complex CTORs must be marked)

  • Injection of public and private fields (object/instance variables)
@injectable
class MyOtherClass {
  @inject
  SomeClass field;

  @inject
  SomeOtherClass _privateField;
}
  • Injection of constructor parameters
@injectable
class MyClass {
  @inject
  MyClass(this.field);

  MyOtherClass field;
}
  • Injection of public and private setters
@injectable
class SomeClass {
  @inject
  set value(SomeOtherClass val) => _privateValue = val;

  @inject
  set _value(SomeOtherClass val) => _anotherPrivateValue = val;

  SomeOtherClass _privateValue, _anotherPrivateValue;
}

The injected objects are configured either by extending the Module class and using one of its bind functions or directly on the Injector.

  • register type MyType.
bind(MyType)
  • register interface MyType to a class implementing it.
bind(MyType).toType(MyTypeImpl)
  • register a singleton
bind(MyType).to(MySuperType).asSingleton();
  • register type MyType to existing object (another way for singleton injections)
bind(MyType).toInstance(object)
  • register a typedef to a function matching it.
bind(MyTypedef).toFunction(function)
  • register MyType to function that can build instances of it
bind(MyType).toBuilder(() => new MyType())
  • use Module to install other modules configuration
class MyApplicationModule extends Module {
  @override
  configure() {
    install(new ComponentModule());

    bind(Emailer).to(EmailerToGMX).asSingleton();
  }
}

Named Injections

DryIce supports named injections by using the @Named annotation. Currently this annotation works everywhere the @inject annotation works.

class MyClass {
  @inject
  @Named('my-special-implementation')
  SomeClass _someClass;
}

The configuration is as before except you now provide an additional name paramater.

bind(MyType, named: "my-name").toType(MyTypeImpl)

The configuration is as before except you now provide an additional name paramater.

Annotated (typed) Injections

You can also use other classes for annotation. works everywhere the @inject annotation works.

@injectable
class UrlGoogle { const UrlGoogle(); }

@injectable
class UrlFacebook { const UrlFacebook(); }

class MyModule extends Module {
  @override
  configure() {
    // annotated
    bind(String,annotatedWith: UrlGoogle ).toInstance("http://www.google.com/");
    bind(String,annotatedWith: UrlFacebook ).toInstance("http://www.facebook.com/");
  }
}

@injectable
class MyClass {
  @inject
  @UrlGoogle()
  String url;
}

The configuration is as before except you now provide an additional annotation.

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 named parameter.
MyType instance = injector.getInstance(MyType, named: "my-name");
  • Get annotated instances directly Instead of using the appropriate annotation to resolve annotated injections you can use the injectors getInstance method with its annotatedWith parameter.
String url = injector.getInstance(MyType, annotatedWith: UrlGoogle);
  • To register and resole configuration values You can use named or annotated registrations to inject configuration values into your application.
class TestModule extends Module {
  configure() {
		bind(String, named: "web-service-host").toInstace("http://test-service.name");
		bind(String, annotatedWith: UrlGoogle ).toInstance("http://www.google.com/");
	}
}

// application code
String get webServiceHost => injector.getInstance(String, named: "web-service-host");
String get webServiceHost2 => injector.getInstance(String, annotatedWith: UrlGoogle);
  • Constructor injection DryIce also support constructors with optional params.
@injectable
class MyClass {
  String getName() => "MyClass";
}

@injectable
class CTOROptionalInjection extends MyClass {
  final String url;
  final String lang;

  @inject
  CTOROptionalInjection(@UrlGoogle() final String this.url,[ final String language ])
      : lang = language ?? "C++";

  @override
  String getName() => "CTORInjection - $url ($lang)";
}

final injector = new Injector()
  ..bind(String,annotatedWith: UrlGoogle ).toInstance("http://www.google.com/")
  ..bind(MyClass).toType(CTOROptionalInjection)
;
final MyClass mc = injector.getInstance(MyClass);
  • Registering dependencies at runtime You can bind dependencies at runtime directly on the Injector.
 injector.bind(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);
  • Install other modules within main module
class MyModule extends Module {
  	configure() {
		register(MyClass).toType(MyClass);
	}
}

class MyMainModule extends Module {
  	configure() {
  	    install(new MyModule());
		register(YourClass).toType(YourClass);
	}
}

var injector = new Injector( new MyMainModule());
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);

Compatibility / migration from di:package

To make migration easier we provide the following functions:

  • Injector.bind is the same as Injector.register.
  • Module.bind is the same as Module.register
  • Injector.get is the same as Injector.getInstance
  • Registration.to is the same as Registration.toType

Be aware that Injector.register and may become depreciated in one of the next releases.

Prefer the bind, to and theget` version over its equivalent.

Thanks

This package is based "Dice" - Thanks Lars Tackmann!

Change Log for dryice

Lightweight dependency injection framework for Dart.

Unreleased

Feature

  • DryIce is now by default Dart 2.x ready and uses reflectable 98c1ed2

Fixes

  • new bind overwrites the previus one (ModuleContainer) 357dcbd

Bugs

  • Remove weird recursive injectableDeclarations-Function 28a92b5

Test

v2.0 - 2018-05-30

Feature

Fixes

  • new bind overwrites the previus one (ModuleContainer) 6aedbe8

Bugs

  • Expected wrong return type for ClassMirror#newInstance a7e1476

Docs

This CHANGELOG.md was generated with Changelog for Dart

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  dryice: ^2.0.15

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:dryice/dryice.dart';
  
Version Uploaded Documentation Archive
2.0.15 Jun 1, 2018 Go to the documentation of dryice 2.0.15 Download dryice 2.0.15 archive
1.8.3 Mar 26, 2018 Go to the documentation of dryice 1.8.3 Download dryice 1.8.3 archive
1.8.0 Mar 26, 2018 Go to the documentation of dryice 1.8.0 Download dryice 1.8.0 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
58
Health:
Code health derived from static analysis. [more]
0
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
0
Overall:
Weighted score of the above. [more]
29
Learn more about scoring.

The package version is not analyzed, because it does not support Dart 2. Until this is resolved, the package will receive a health and maintenance score of 0.

Issues and suggestions

Support Dart 2 in pubspec.yaml.

The SDK constraint in pubspec.yaml doesn't allow the Dart 2.0.0 release. For information about upgrading it to be Dart 2 compatible, please see https://www.dartlang.org/dart-2#migration.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.9.0 <2.0.0