Created
April 7, 2016 00:18
-
-
Save yjbanov/0aeba2238b087e37d3becd5afacf3251 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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