>
> I have taken a look at Merlin (these classes:
> http://cvs.apache.org/viewcvs.cgi/jakarta-avalon-excalibur/assembly/src/
> java/org/apache/excalibur/container/lifecycle/ )
> and as far as I can see, the pluggable pipeline stages (or phases, or
> whatever), are limited to act on (1) the component/object and (2) the
> Context.
Yes, the initial idea was that the pluggable lifecycle stages
would operate on the component, using whatever objects they required
from the Context object if any.
> So... not only will the component have a type specifier that explains
> what context entries it requires and what special lifecycle handlers
> it requires - those handlers will also have a context requirements.
Yes, this is true as well. The Fortress implementation doesn't
check any context entries, however IIUC the Merlin implementation
treats the handlers as regular Components with validation, dependancy
resolution, etc.
> So if you have a SpiffyLifeCycleStage that makes components all spiffy
> as they come through it, how is that SpiffyLifeCycleStage going to do
> it without support from the container to put a Spifficator (the means
> to make a component spiffy) in the context?
My original idea was that the context be filled with these objects
(the Spifficator for example) before the application starts
operating - as is done in Cocoon - I know it's not the most optimal
solution but something I could work with at the time.
I brought this up on the list several weeks back and Berin came up
with the Session idea which is an alternative solution for storing
such transient objects (more info under
http://marc.theaimsgroup.com/?l=avalon-dev&m=102742811501755&w=2).
> If you have a PersistentLifeCycleStage, how are you going to obtain
> the persistence mechanism if the container doesn't give it to you via
> the context?
If not via the Context, via the CM in Merlin (and I presume in fortress
too in time) or the Session object described above, or some non-OO
way (ie. static method, singleton getInstance(), etc)
> The problem with populating the context with any non-constant entries
> (such as a Spifficator) has already been discussed and found to have
> no solution short of mind-reading the programmer and sprouting new code
> on startup/linking.
I think this must have been before my time here, is there a reference
you can send me so I can read up on what was discussed ?
> At the moment, the lifecycle extensions appear to be shiny new features
> that while nice in theory are useless in practice. I'm afraid that any
> container trying to implement them in a useful way will (1) never be
> completed and (2) implode under its own weight. It's just too much "do
> everything", too much genericism, in it.
>
> Miscellaneous issues:
>
> + Will the lifecycle handler need a component/service manager?
> How will a DB-persistence handler work? Will it use the Excalibur
> Datasource component? How will it access it?
Initially lifecycle handlers were just classes, after looking at
Stephen's component-oriented approach in Merlin I think there's
advantages having the handlers be components. A handler that is
a component would be able to access your DB-persistence component
described above.
> + If the handler requires another component, has a context and surely
> will need a configuration, what is the difference between it and
> a component?
If the handler requires all that's listed above, then nothing - but
remember lifecycle extensions are trying to let you reuse code across
*multiple* perhaps unrelated components, like the standard ones do.
If you only needed the handler 'component' once, you wouldn't worry
about defining a new lifecycle stage for it. But imagine the case
when you have many components that you want to add such
'component decorating' functionality to.
It's possible to add the functionality by looking up a depdendent
component, or call a static method or access the context, etc, in all
of the component implementations - and this works if the components are
related via base classes, etc, but if the classes aren't related
then you end up duplicating code.
eg. imagine if LogEnabled didn't exist and each component had to
access some 'Manager' class to get a Logger object. It's manageable if
they all
extend some base class that does the work, but if not, the code
accessing
the 'Manager' class needs to be copied all over the place. It's much
nicer
if the CM passes the Logger to the Component, plus follows SoC and is
one
of the excellent advantages when one uses Avalon.
This was what I wanted to solve for domain specific components that
had requirements like the need for LogEnabled across many unrelated
components, following the SoC/IoC model we already advocate.
Each domain has its own requirements, and can implement their own
interfaces applicable to their needs.
In our project for example, we have many classes that perform database
access. The decision as to which database you use depends on who you
are, where you are geographically located, and some other factors that
make accessing your database a little complicated.
I wrote the code to select the applicable database for the current
thread, but had no easy way to share this code amongst other unrelated
classes.
Now I've defined a Queryable interface with an extension class that
calls
upon the interface at access time to set the correct database for the
current thread, and the code which does the database selection is now
completely localised to one method on the extension class. For this,
extensions were very useful in helping me reuse that code.
I'm sure TIMTOWTDI, but I wanted to follow what we already advocate
(ie.
the SoC approach). That way, developers in our project already familiar
with the Avalon concepts can easily grasp how to use the new extensions
when writing our components.
In particular its useful when using tools like Cocoon where you don't
have as much control over what base classes are being extended.
> + Go back to the final proposal for A5. Doesn't it solve everything
> by allowing/requiring you to specify handlers/factories for
> components?
Almost, I looked at handler/factory specification as a possible solution,
but it required IMO too much subclassing to handle extending the 4
phases of
a components life (ie. access release create destroy).
Most handlers use the same factory - allowing you to create a custom
factory that handles create & destroy extensions, but the operations of
accessing & releasing a component are done by the component handler
(PoolableComponentHandler, PerThreadComponentHandler, etc) which means
a new subclass for each set of extensions for each handler.
Hope that helps mate ? :)
Cheers,
Marcus
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>