This is a follow up to the threads:
   [RT] IoC Type Who Cares?
   [proposal] IoC type 3.14 extension to the Avalon Framework

If you are coming into this discussion late in the game, you may want to review the 
above threads for more detail.


The Avalon Framework is a component framework that defines a conversation that can 
take place between a component and its container.  Its definition of a container is 
currently very loose, which is ideal.  However, there are advantages to defining an 
optional container framework.  Take PicoContainer for example; Pico's "type 3" 
components may operate (conceptually) in many different containers, and PicoContainer 
can be extended/implemented/mix-n-matched to come up with a wide variety of containers 
that can run type-1, type-2, or type-3 components.  It is very flexible, and the Pico 
folks have come up with a lot of great ideas.  However, the framework (Pico's), in my 
opinion, has some short-comings.  In addition, many developers will want to work with 
a "pure Avalon" solution or a framework that is more tightly bound to the Avalon way 
of doing things.  It it my proposal that we give them one.


public interface RoleResolvableServiceManager
extends ServiceManager {

    /* BEGIN from ServiceManager **
    boolean hasService(String role);

    Object lookup(String role)
      throws ServiceException;

    void release(Object service);
    ** END from ServiceManager */

    String resolveRole(Class serviceInterface)
      throws ServiceResolutionException;
}


public interface ServiceConstructor {

    String getServiceRole();
    Class getServiceInterface();

    Object newService(RoleResolvableServiceManager serviceManager,
                      Context context)
      throws ServiceResolutionException,
             ServiceInstantiationException;

    void verify(RoleResolvableServiceManager serviceManager)
      throws ServiceResolutionException;
}


public interface ServiceContainer
extends ServiceManager, Disposable {

    String ROLE = ServiceContainer.class.getName();

    ServiceConstructor getConstructor(String role);

    void registerService(ServiceConstructor sc)
      throws ServiceRegistrationException;

    void unregisterService(String role);

    /* BEGIN from ServiceManager **
    boolean hasService(String role);

    Object lookup(String role)
      throws ServiceException;

    void release(Object service);
    ** END from ServiceManager */

    Collection getServices();
    Set getServiceRoles();

    // Uncertain about this method...
    // The List can be modifiable/unmodifiable
    List getChildContainers();

    void verify()
      throws ServiceResolutionException;

    // from Disposable
    void dispose();
}


Now, I AM NOT advocating the above framework carte-blanche.  It is a brainstorm.  What 
I AM advocating is simply the existence of a container framework.  But since I am 
brainstorming, I will attempt to give a walk-through.

The two crucial pieces of this puzzle are ServiceConstructor and ServiceContainer.  
These are intended to be as loosely coupled as possible.  My goal was that 
ServiceConstructor(s) could be plugged in to ServiceContainer implementations, 
regardless of the vendor.

A ServiceContainer is an abstraction that defines the ability to register a service, 
to lookup a service (it extends ServiceManager), to list all available services within 
the container, and to verify all dependencies within the container.  I borrowed 
heavily from PicoContainer, but I believe that my design is more straightforward and 
more easily implemented.  And while I do like the idea of 
PicoContainer.getComponentMulticaster*, I don't think it belongs within the container 
interface itself.  A better idea (IMHO), would be something like:

    multicasterFactory.createServiceMulticaster(container);

As you may notice in ServiceContainer, I have stuck with the notion of Avalon roles.  
This complicates things slightly when using IoC type 3.  These roles need to be able 
to be mapped with their service interfaces.  This is the reason for the 
RoleResolvableServiceManager and resolveRole.  A straightforward 
RoleResolvableServiceManager.resolveRole implementation would be simply to attempt to 
find the static field "ROLE" or to use the fully qualified interface name and then 
invoke ServiceManager.hasService.

A ServiceConstructor is where the IoC type implementation is buried.  It  may support 
type-1, type-3, type-3, or type-X components.  A ServiceConstructor exposes the role 
that a service is to fulfill.  It also exposes the interface a service is to 
implement, but it does not expose the implementation class itself.  I feel that this 
is more flexible.  It provides a verify() method which can be used to check if the 
given ServiceManager can resolve all of its dependencies.  It also, quite naturally, 
provides a newService() method which can be used by the ServiceContainer to 
instantiate a registered service.  The arguments provided to 
newService(RoleResolvableServiceManager,Context) allow the constructor to resolve all 
services (using ServiceManager) and/or container-dependent instruments (using Context).

The entire framework was designed primarily with ease-of-implementation in mind.  A 
straightforward ServiceContainer implementation would extend 
RoleResolvableServiceManager and pass along itself into the ServiceConstructor 
methods.  A more security conscious implementation might differ.


Any questions, comments, criticisms?


Thanks!
Jonathan Hawkes

Reply via email to