Bernd Fondermann wrote:
Having setters to inject service components (Store, DNSServer and all the others) into the respective objects creates a new chance to take another step to dramatically lower the dependency on Avalon and centralize the service lookup code.

You're almost precisely describing my ideas ;-) thanks!
Differences in preferences follow:

A utility class "AvalonServiceInjector" could automatically inject all needed services. The manual lookup code would become obsolete.

I would call it ContainerUtil (ala Avalon) so we can use it later for lifecycle management and more.

This yields the chance to remove dependencies on Avalon's ServiceManager from all components.
[...

public void service( final ServiceManager componentManager )
        throws ServiceException {
        super.service(componentManager);

        new AvalonServiceInjector(componentManager).canoncialInject(this);

}


Note: the whole injection line could even be moved out to the caller of service() and make service() redundant in most of the cases.

Right. We should remove the whole service method and put the injector util in a component wrapper (or in the mailet/matcher loader for mailets and handlerchain for handlers).

This is how the utility works:
[...
The beef happens to happen in all-purpose ServiceInjector which is already totally independent of Avalon. It uses reflection to gather all setters and tries to find fitting objects in ServiceManager:
[...

I would prefer Enabling interfaces over setter reflection in order to use AutoWiring because it is more selfdocumenting. This comes at the cost of an additional interface for every service but it allow the developer to declare that a specific setter is there to satisfy a dependency.

e.g: We have UsersRepository, we add a UsersRepositoryAware interfaces:
interface UsersRepositoryAware {
void setUsersRepository(UsersRepository ur);
}
then when you write a component that need this service you write the setter (as you already did for your proposal) and you also add "implements UsersRepositoryAware".

Furthermore I want to add that autowiring (either by setter reflection or enabling interfaces) is a cool thing but it is also an obfuscator and it sometimes limit your flexibility. A fix to this problem is to rely on super-container declarations (see assembly.xml and avalon ServiceManager) or to provide our own way to declare "service roles".

This works perfectly after renaming those setters not already strictly following the setter naming convention.

By evaluating the canoncialInject() return code the component has full control to check whether all of its components have been injected.

  Bernd

Often, when setter injection (with or without enabling interfaces) is used a serviced() lifecycle method is added to give to the object the opportunity to verify the dependencies we received and start its own "work". Maybe we can do this at the beginning of another already existing lifecycle.

Stefano


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to