The Merlin project is committed to ....
A component is a logical unit of one or more classes and related artifacts which together implement a functionality. A component delivers his functionality only through its "component interface". There can be one or more "component interface implementations".
A component is not aware of its functional environment - eg. a component can be deployed predictably in different application scenarios and environments.
A component is always responsible for the correctness of the incoming data / objects.
A component is described by a "component type descriptor" (Type) which holds immutable information associated with the component implementation and its interface (Metadata). Based on information accessible from an instance of Type a container has available the structural and runtime dependencies that an instance of a corresponding component will require.
In Merlin metadata are stored either in XML or in a binary format. Metadata are created automatically by "Magic" - which is the build tool for Merlin - or by Eclipse Studio from JavaDoc tags contained in the components interface or implementation.
Components in Merlin can get their information either through a freely configurable and extendable set of interfaces or by constructor injection.
The following set of interfaces are delivered as standard by Merlin:
- Lifestyle Management
- Merlin provides support for different component instantiation policies. These policies are referred to as lifestyles. Examples of lifestyle include 'singleton', 'per-thread', 'pooled' and 'transient'.
- Lifecycle Management
- Merlin provides support for constructor based injection of lifecycle artifacts, or optional phased delivery under which a component is processed through a series of lifecycle stages. Lifecycle processing involves the execution of a series of stages such as associating a logging channel, applying a configuration or component parameters, setting the runtime context, supplying dependent services, initialization, startup, shutdown and disposal. Within the Merlin system, lifecycle stages can be extended or modified through association of other components that provide lifecycle support. Merlin distinguishes these services as deployment dependencies as distinct from classic runtime dependencies.
In Merlin a block is a logical and physical unit of one or more components and its related artifacts. One artifact is the blocks metadata which contains information like its containing components, classloader directives and the "services" it delivers.
Other artifacts of a block might be persistence mapping information for contained components etc.
Physically a block is deployed in a standard jar file. To make it possible to identify blocks visually Merlin blocks are using the ".bar" file extension.
It's quite usual that the term "block" and the term "component" are used equivalent.
A block can declare the export of a set of services established by the components contained within it. This enables a container to function as a composite component relative to its peers. This composition is either done by "nested" or by "referenced" blocks.
An "include" directive in a block instructs Merlin to include an external block within the container. Services exported by the block will be made available to other components at the same level as the included block
With the "include" directive a block is included "by value" into a block. This is especially useful to structure larger blocks into smaller reusable blocks.
A "container" directive is used to reference other blocks / containers. Only services declared in the referenced block are accessible by the parent block. This directive is used to assemble a whole application by reusable blocks.
In Merlin every block is covered by its own container. The "startup" program, which instantiates and manages all the subsequent containers is called the "kernel".
Through that architecture Merlin assures a very secure and encapsulated runtime environment for each block.
Merlin differentiates two types of blocks: On one hand "application blocks" and on the other hand "Facilities".
Facilities are just normal blocks with the exception of:
- Facilities are able to access the kernel and its container model.
- Facilities are used to extend the functionality of the core Merlin container in a plugable and flexible manner.
- Facilities include technical services like JMX, messaging, logging, persistence, workflow etc.
This separation of concerns enables the enhancement or even exchange of kernel implementations without touching the implementation of the application blocks. This is one of the key features of Merlin which ensures on one hand a large stability for application blocks against technology change and on the other hand a high flexibility to adopt new technologies and to enhance the core functionality of Merlin.
Application blocks may also be hierarchically composed. But because this is not naturally darstellbar it is limited to one block.