james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bernd Fondermann <bf_...@brainlounge.de>
Subject Re: Central class for service injection
Date Wed, 12 Jul 2006 11:49:48 GMT
Stefano Bagnara wrote:
> 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.

I'd call a ServiceInjector a "ServiceInjector" ;-) But I have no problem 
to encapsulate instantiation + call in a Lifecycle utility class.

> 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).

OK.

> 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".

OK, I see the advantage that it is more verbose. But has the downside 
that you have
a. to declare the interface
b. add implements clause where service is used
c. add injection code, probably resulting in a copy/paste-like stanza 
for injecting

but I agree that verbosity here may be more important.

we could still use reflection if we used the convention, that such 
interfaces have to be named for example UsersRepositoryServiceAware and 
we could add a "interface.endswith("ServiceAware")"-check to my proposed 
code.

> 
> 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".

As far as I can see, this "flexibility" Avalon/Phoenix provides is not 
used anywhere right now. So the flexibility with all the roles, xinfo, 
assembly.xml becomes a bunch of over-verbose, redundant configurations 
where simply class-/interface-names are repeated all over.

> 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.

+1

   Bernd

---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message