Skip to content

Instantly share code, notes, and snippets.

@yjbanov
Created April 7, 2016 00:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yjbanov/0aeba2238b087e37d3becd5afacf3251 to your computer and use it in GitHub Desktop.
Save yjbanov/0aeba2238b087e37d3becd5afacf3251 to your computer and use it in GitHub Desktop.
dynamic _createNewInstance(Type type, Provider provider, Injector injector) {
final arguments = provider.dependencies.map(injector.get).toList(growable: false);
return provider.factory(arguments);
}
/// Vends injectable objects, deciding whether they need to be created or
/// reused.
abstract class Scope {
dynamic getInstance(Type type, Provider provider, Injector injector);
}
/// Creates a new instance every time.
///
/// This is a polar opposite of [SingletonScope].
class DefaultScope implements Scope {
const DefaultScope();
dynamic getInstance(Type type, Provider provider, Injector injector) {
return _createNewInstance(type, provider, injector);
}
}
/// Creates one instance once for the entire lifetime of the application.
///
/// This is the polar opposite of [DefaultScope].
class SingletonScope implements Scope {
dynamic _cachedInstance;
SingletonScope();
dynamic getInstance(Type type, Provider provider, Injector injector) {
if (_cachedInstance == null) {
_cachedInstance = _createNewInstance(type, provider, injector);
}
return _cachedInstance;
}
}
/// Creates one instance once per zone.
class ZoneScope implements Scope {
/// Since the root zone is not created by the application, there's no way to
/// create a cache for it. This serves as the fallback when the lookup reaches
/// the root zone.
static final Map _rootZoneCache = {};
dynamic getInstance(Type type, Provider provider, Injector injector) {
Map cache = Zone.current['cork-zone-scope-cache'] ?? _rootZoneCache;
dynamic instance = cache[type];
if (instance == null) {
cache[type] = instance = _createNewInstance(type, provider, injector);
}
return instance;
}
}
/// A resolved factory function for a type of [T].
class Provider<T> {
/// A factory function that returns an instance of [T].
final Factory factory;
/// Dependencies required for [factory] to be executed (arguments).
final List<Type> dependencies;
final Scope scope;
const Provider(this.factory, [this.dependencies = const [], this.scope = const DefaultScope()]);
@override
bool operator==(Provider<T> other) {
return
identical(this, other) ||
factory == other.factory &&
const IterableEquality().equals(dependencies, other.dependencies);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment