Metro introduces the principal of "Context Assertion" by a component and the corresponding subject of "Context Awarness" by a container. In a Metro environment (or any environment following the context pattern) a component asserts its operational dependencies via an inner Context interface.
Key benefits arrising from the usage of the Context Assertion pattern include:
- Operations are 100% type safe.
- Explicit declaration by the component of optional versus required dependencies.
- No ambiguity between dependency management and component implementation.
- Dependencies are fully qualified.
- No container dependencies.
The following example component declares a inner Context interface containing three operations - the first operation returns an instance of java.awt.Color, the second operation returns a primitive int value and the third a String value. The last example includes a default value parameter.
import java.awt.Color;
public class DemoComponent
{
public interface Context
{
Color getColor();
int getLength();
String getName( String defaultName );
}
public DemoComponent( Context context )
{
final Color color = context.getColor();
final int length = context.getLength();
final String name = context.getName( "widget" );
...
}
}
Context declaration relies upon a set of patterns that are applied to operation signatures. First and formost is the usage of the bean-style getXxxx() naming convention wherein "get" is a standard prefix and the remainder of the method name is used to establish a unique context entry key. A second pattern is used to determine if the context operation is optional or not. If the operation declares a single parameter then the context entry is considered optional.
Two constraints exist concerning context operation signatures:
- An operations may not declare a throws clause.
- If an operation declares a default parameter the type of the parameter must be type assignable to the operations return type.