Inversion of Control |
Seems like Inversion of Control is all the rage these days. The Avalon project is completely based around it. Avalon uses detailed assembly descriptions to tie services together ... there's no way an Avalon component can "look up" another component; in Avalon you explicitly connect services together.
That's the basic concept of Inversion of Control; you don't create your objects, you describe how they should be created. You don't directly connect your components and services together in code, you describe which services are needed by which components, and the container is responsible for hooking it all together. The container creates all the objects, wires them together by setting the necessary properties, and determines when methods are invoked.
More recently, this concept has been renamed Dependency Injection.
There are three different implementation pattern types for IoC:
type-1 | Services need to implement a dedicated interface through which they are provided with an object from which they can look up dependencies (other services). This is the pattern used by the earlier containers provided by Avalon. |
type-2 | Services dependencies upon are assigned via JavaBeans properties (setter methods). Both HiveMind and Spring use this approach. |
type-3 | Services dependencies are provided as constructor parameters (and are not exposed as JavaBeans properties). This is the exclusive approach used by PicoContainer, and is also used in HiveMind and Spring. |
HiveMind is a much looser system than Avalon. HiveMind doesn't have an explicit assembly stage; it wires together all the modules it can find at runtime. HiveMind is responsible for creating services (including core implementations and interceptors). It is quite possible to create service factories that do very container-like things, including connecting services together. hivemind.BuilderFactory does just that, instantiating an object to act as the core service implementation, then setting properties of the object, some of which are references to services and configuration point element data.
In HiveMind, you are free to mix and match type-2 (property injection) and type-3 (constructor injection), setting some (or all) dependencies via a constructor and some (or all) via JavaBeans properties.
In addition, JavaBeans properties (for dependencies) can be write-only. You only need to provide a setter method. The properties are properties of the core service implementation, there is no need for the accessor methods to be part of the service interface.
HiveMind's lifecycle support is much more rudimentary than Avalon's. Your service implementations can get hivemindcallbacks when they are first created, and when they are discarded, by implementing certain interfaces.
Purist inversion of control, as in Avalon, may be more appropriate in well-constrained systems containing untrusted code. HiveMind is a layer below that, not an application server, but a microkernel. Although I can see using HiveMind as the infrastructure of an application server, even an Avalon application server, it doesn't directly overlap otherwise.