Under Metro all dependencies of a component are expressed using a context interface. The Metro runtime will evaluate the interface, build an implementation, and populate the implementation taking into account data supplied under a deployment directive, together with datatype and option/required status of respective context entries.
The following example demonstrates the declaration of a context via the implicit inner-interface pattern (i.e. an inner interface named Context). The context interface declare four entries - "count", "label", "backgroundColor" and "gizmo". The count and gizmo entries are non-optional whereas the remaining two entries are classes as optional. At runtime a container is required to construct and populate the supplied context implementation ensuring that all non-optional entries have resolvable values. A container may provide values for non-optional entries, however client code may assume that client supplied argument may be returned back to the client.
public class Widget { public interface Context { int getCount(); String getLabel( String value ); Color getBackgroundColor( Color color ); Gizmo getGizmo(); } public Widget( final Context context ) { int count = context.getCount(); String label = context.getLabel( "Hello" ); Color color = context.getBackgroundColor( Color.RED ); ... } }
context | an interface (or implementation) referenced as a component constructor parameter defining the dependencies (resources and services) that a component has on its environment |
entry | a context interface is composed of a series of accessor methods - each method reflects the entry name plus the "get" prefix |
nesting | a nested context is a context entry that has a return type that is a context interface |
annotation | an annotation used to mark an interface as compliant with the context contract |
contract | the rules and constraints applicable to a context interface (see below) |
A context interface is identfied using either of the following:
- Explicit assertion using the context annotation marker.
- Implicitly resolved by locating an inner interface within the target component class named Context.
The context interface may declare 0 or more accessor methods (subject to the following constraints) where each method establishes a logical context entry.
- A method may not declare the void return type (the Metro runtime fully supports primative, complex, and array return types).
- An entry method with zero parameters is deemed to be a required entry.
- Entry methods declaring a single parameter are deemed to be optional entries. The parameter type of an optional entry must be assignable to the method return type.
- Entry methods may not declare exceptions.
Each method signature is used to resolve the following feature of the respective context entry
name | resolved using Java Bean method naming conventions (i.e. a method named getKeystore identifies an entry named "keystore") |
type | the method return type identified the class of the object associated with the context entry |
optional | the optional or required status of the entry is resolved by the presence or absence of a method parameter - if the method takes a single parameter, the entry is classed as optional, whereas a method without a parameter is classes as a non-optional entry |
A Context interface declares the dependencies that a component has on its environment. The solution to these dependency constraints is a function of the container implementation. The Metro runtime provides services supporting preconfigured packaged profiles combined with url based deployment directives as the default DPML deployment solution.