toothpick-runtime / toothpick / ScopeNode

ScopeNode

abstract class ScopeNode : Scope

A scope is one of the most important concept in Toothpick. It is actually important in Dependency Injection at large and Toothpick exposes it to developers.

Conceptually a scope contains toothpick.config.Bindings & scoped instances :

binding is way to express that a class Foo is bound to an implementation Bar. It means that writing @Inject Foo a; will return a Bar. Bindings are valid for the scope where there are defined, and inherited by children scopes. Children scopes can override any binding inherited from of a parent. Modules allow to define s and are installed in scopes. scoped instance a scoped instance is an instance that is reused for all injection of a given class. Not all bindings create scoped instances. Bindings Foo to an instance or to a instance means that those instances will be recycled every time we inject Foo from this scope. Scoped instances are all lazily initialized on first injection request.

In toothpick, Scopes create a tree (actually a disjoint forest). Each scope can have children scopes. Operations on the scope tree (adding / removing children, etc.) are non thread safe. The implementation of Toothpick provides a Toothpick class that wraps these operations in a thread safe way.

Scopes can be support scope annotations: annotation classes qualified by the annotation. All classes annotated by this annotation will automatically be scoped by Toothpick in the scope that supports them.

Classes that are not annotated with a javax.inject.Scope annotation, also called un-scoped classes, are not associated to a particular scope and can be used in all scopes. Their instances are not recycled, every injection provides a different instance. Scoping a class by annotation is conceptually exactly the same as binding it to itself in a scope.

Scope resolution : when a class is scoped, either by binding it in a module and then installing this module in a scope, or by adding a javax.inject.Scope annotation, it means that all its dependencies must be found in the scope itself or a parent scope. Otherwise, Toothpick will crash at runtime when first instantiating this class. The only other allowed alternative is to have an un-scoped dependency.

Constructors

<init>

ScopeNode(name: Any)

Functions

equals

open fun equals(other: Any?): Boolean

getName

open fun getName(): Any

getParentScope

open fun getParentScope(): ScopeNode
open fun <A : Annotation> getParentScope(scopeAnnotationClass: Class<A>): ScopeNode

getRootScope

open fun getRootScope(): ScopeNode

hashCode

open fun hashCode(): Int

isScopeAnnotationSupported

open fun isScopeAnnotationSupported(scopeAnnotationClass: Class<out Annotation>): Boolean

supportScopeAnnotation

open fun supportScopeAnnotation(scopeAnnotationClass: Class<out Annotation>): Scope

Binds a scopeAnnotationClass, to the current scope. The current scope will accept all classes that are scoped using this scopeAnnotationClass.

Inheritors

ScopeImpl

open class ScopeImpl : ScopeNode

{@inheritDoc}

A note on concurrency :

  • all operations related to the scope tree are synchronized on the Toothpick class.
  • all operations related to a scope's content (binding & providers) are synchronized on the key (class) of the binding/injection.
  • all providers provided by the public API (including Lazy) should return a thread safe provider (done) but internally, we can live with a non synchronized provider.
All operations on the scope itself are non thread-safe. They must be used via the Toothpick class or must be synchronized using the Toothpick class if used concurrently.