-
Notifications
You must be signed in to change notification settings - Fork 44
Home
A Motif Scope is the top-level container for all other Motif features.
@motif.Scope
interface FooScope {}- Interface annotated with
@motif.Scope - Must be an interface
- Analogous to Dagger Component or Subcomponent
An access method allows access to objects on the dependency graph defined by the Scope.
@motif.Scope
interface FooScope {
Bar bar();
...
}- Analogous to Dagger Component provision method
Child methods declare Scopes as child Scopes of other Scopes.
@motif.Scope
interface ScopeA {
ScopeB b();
}
@motif.Scope
interface ScopeB {
ScopeC c();
}
@motif.Scope
interface ScopeC {}In the example above...
ScopeA -> ScopeB -> ScopeC
-
ScopeBis a child Scope ofScopeA -
ScopeCis a child Scope ofScopeB -
ScopeCis a descendant Scope ofScopeA -
ScopeAis a parent Scope ofScopeB -
ScopeBis a parent Scope ofScopeC -
ScopeAis a ancestor Scope ofScopeC
Any dependencies provided by an @Expose-annotated factory method are automatically available to child or descendant Scopes. See @Expose for details.
A child method allows the creation of child Scopes.
@motif.Scope
interface FooScope {
BarScope bar();
BazScope baz(SomeDependency d);
...
}- Declared on top-level Scope interface
- Returns a type that is itself a Scope
- Dependencies provided by @Expose-annotated factory methods are automatically available to child and descendant Scopes
- Parameters define dynamic dependencies
- Analogous to Dagger Subcomponent factory method.
Dynamic dependencies allow contributions to the Motif DI graph for dependencies that can't be statically provided by the parent or child Scope. The canonical example is passing an AuthToken retrieved from the network to a child Scope. The AuthToken in the example below is made available to all child factory methods.
@motif.Scope
interface OnboardingScope {
LoggedInScope loggedIn(AuthToken authToken);
...
}- Defined as parameters on child methods
- Multiple parameters allowed
- Dynamic dependencies are available to the immediate child Scope
- Dynamic dependencies are NOT transitively available to grand-child Scopes or further descendants
Similar behavior can be accomplished with Dagger's @BindsInstance or passing dependencies to a @Module constructor.
A @motif.Objects-annotated class nested in a Motif Scope interface defines Motif factory methods.
@motif.Scope
interface FooScope {
@motif.Objects
class Objects {}
}- Defined as a nested class of a Scope interface
- Declares factory-methods
- May not define any non-static fields
- May not define any constructors
- Analogous to Dagger @Modules
Factory methods tell Motif how to construct dependencies.
@motif.Scope
interface FooScope {
@motif.Objects
class Objects {
Foo foo(Bar bar) {
return new Foo(bar);
}
Bar bar() {
return new Bar();
}
}
}- A provided dependency is the type instantiable by a factory method
- Required dependencies are the types required by a factory method in order to instantiate the provided dependency
- A Factory method can be one of three types: Basic, Constructor, or Binds
- A provided dependency is defined by the return type of the factory method
- Required dependencies are defined differently based on the type of the factory method
- A factory method is valid if all required dependencies are provided either by factory methods defined on the same Scope or by @Expose-annotated factory methods defined on ancestor scopes.
- A factory method must not return void.
- Analogous to Dagger @Module methods
Motif invokes basic factory methods directly in order to instantiate the provided dependency.
@motif.Scope
interface FooScope {
@motif.Objects
class Objects {
Foo foo(Bar bar) {
return new Foo(bar);
}
Bar bar() {
return new Bar();
}
}
}- Method must NOT be
abstract - Required dependencies are defined by method parameters
- Analogous to Dagger @Provides method
Motif uses the constructor directly to instantiate the provided dependency.
@motif.Scope
interface FooScope {
@motif.Objects
abstract class Objects {
abstract Foo foo();
abstract Bar bar();
}
}
class Foo {
@javax.Inject
Foo(Bar bar) {...}
Foo() {...}
}
class Bar {}- Method must be
abstract - Method must be parameterless
- Required dependencies are defined by provided dependency constructor parameters
- If the provided dependency defines multiple constructors...
- Exactly one constructor must be annotated with
@javax.Inject - Motif will use the
@javax.Inject-annotated constructor for instantiation
- Exactly one constructor must be annotated with
- Analogous to Dagger constructor injection
Motif uses an instance of the method parameter type to provide the provided dependency.
@motif.Scope
interface FooScope {
@motif.Objects
abstract class Objects {
abstract Foo foo(Bar bar); // Binds
abstract Bar bar(); // Constructor
}
}
interface Foo {}
class Bar implements Foo {}- Method must be abstract
- Method must define exactly one parameter
- Parameter must be assignable to return type
- Parameter defines the single required dependency
- Analogous to Dagger @Binds methods
TODO
TODO
TODO
TODO