Contextual Singleton pattern

A pattern where only a single instance of a given type is reachable through a contextual mechanism, such as a container.

This pattern is derived from the Singleton pattern, where only a single "global" instance of a given type is instantiated and made reachable.

The Contextual Singleton pattern permits a software component to resolve references to other required components using only a reference to the interface or base type known to the requesting component. A component that depends on another is likely to know what type of object it is looking for, and thereby supplies information to the container to resolve the single instance of that type (which may of course be a subtype or an implementation of the request type).

Benefit

The primary benefit of the Contextual Singleton pattern is to reduce coupling, redundancy, and Layer Entanglement by reducing the need for the application developer or deployer to maintain an additional naming system for application components in order to achieve dependency injection.

When components need to be assigned names in order to be referenced by other components, mechanisms to manage, publish, configure, resolve, reflect on, and document these names must be implemented by the component developer and the container, and attended to by the integrator, often within another layer of the application. In addition, these naming mechanisms should ideally provide safety mechanisms to expose any misconfiguration at load-time or other early stage, and to resolve conflicts.

As more components are involved, the complexity of this task increases, as does the impact on the application layer which bears this burden. The affected application layer usually ends up being a presentation or deployment layer, which can often get cluttered with the explicit "wiring" of lower level components through global names. The question of where a name is defined and referenced becomes non-obvious, but critical to debugging. The complexity of the underlying application ends up leaking into other layers, with the undesirable effect of increased coupling and decreased encapsulation.

If the system is designed so as to permit granular customization and extension of various subsystems, it becomes necessary to expose a large number of application components and their associated customization and binding points. Doing so using externalized naming systems to resolve all dependencies would be extremely complex. Maintaining multiple customization layers (say, a base layer, an industry specific layer, and a company specific layer) without solving this problem would likely be difficult.

The use of the Contextual Singleton pattern with a fine grained contextual structure (eg. the hierarchical containership model of a markup document, for instance) provides a means for several components in one layer with different scopes (eg. request, session, application) to resolve dependencies to each other without involving other components or other layers in this process.

By using a specific-enough subtype or interface identifier to request a dependency instead of an externally defined "name", and by preventing ambiguity by providing a means to publish an instance of this subtype or interface at a level of context close enough to the requester to ensure that only one instance will be available, the Contextual Singleton pattern significantly reduces the need for external coupling. This in turn makes it much easier to manage references locally without affecting other application layers.


Usage

In the Spiralcraft Framework, the Contextual Singleton pattern is implemented using a Focus chain, and is accessed via the spiralcraft.lang Focus resolution syntax element, and programmatically through the spiralcraft.lang.Focus.findFocus(URI typeURI) method. Each Focus in the chain references a parent Focus and represents a level in the containership hierarchy. The subject of each Focus and all of its base types and interfaces is made available to components, with components in the immediate context (ie. at the end of the chain) taking precedence.