There's no reason we can't have multiple dependency resolution schemes. For example, we could support all three IoC types (as defined by the
PicoContainer project). I do something like that in my JingDAO project
already. This would also allow us to better support:
- older Avalon components - traditional JavaBeans - Pico-style components
One issue would be determining which dependency scheme to use. It could potentially be done dynamically by first trying the contructor, then any bean properties and finally via the service() method.
Avalon components generally expect service() before any non-framework methods so you probably want to reverse that.
The meta-info might also be able to store this information, but I would like it to be as automagical as possible, making it easier for component writers.
+1
In the end though, you'll still be stuck with older Avalon components which use the service manager for both dependencies and discovery. I personally would like to see the service manager used more for discovery than dependency resolution.
I'd define a new interface instead. Or, more likely, just use JNDI for discovery.
I'm working on some ideas for this now -- should have something a little more concrete tomorrow. Any other thoughts or comments would be appreciated.
been playing in the same area :D
1) Option: algorithm -------------------- I've found an algorithm that seems to work reasonably well in practice:
1) select the longest available constructor ('pure' pico components will
have only one; avalon and XWork normally only have a default no-argument
constructor). Check to see if you can satisfy all its arguments. If not,
pick the next longest one. If none is left, throw a dependency
resolution exception.2) create an instance
3) look for all avalon lifecycle interfaces and call the appropriate methods
4) look for all XXXAware interfaces and call the appropriate methods as per XWork semantics
5) call any tellInitComplete() method (or whatever its called) to signal XWork-style components that you're done setting them up
The main disadvantage is that this is slow (lots of introspection). You also need to be very careful with 'hybrid' components whose state will be initialized and overridden a few times (consider providing a datasource in the constructor, through the service manager and through a DataSourceAware interface: the component might open three connections), hybrid components which don't allow you to call a non-empty constructor and avalon lifecycle methods (ie they are picky about their state validation), etc etc. Haven't actually encountered any that were any kind of problem.
You also can't really support all springframework-style components this way.
The main advantage with an algorithm like this is that a component author doesn't have to specify what kind of component he is writing, ie, no
/** @@ComponentType( ComponentType.AVALON ) */
Within merlin, of course, you also need to accept a lot more "sensible defaults", like "expose all interfaces I implement as work interfaces". It is possible to move away from that a little bit by excluding known marker interfaces (ThreadSafe), but I found that not worth the hassle (there will always be unknown marker interfaces).
2) Option: springframework -------------------------- Springframework has an xml composition language that should allow you to support avalon-framework by virtue of a long configuration file. Ie:
<spring>
<instance id="sm" class="DefaultServiceManager"
interface="ServiceManager"><put arg0="my-service" arg1="urn:spring:ref:my-service"/>
</instance> </spring>
or whatever their xml format looks like. Needless to say, this is ugly; to a much greater degree than ant or jelly scripts.
3) Option: jython ----------------- "Replace an ugly xml scripting language with a beautiful much cleaner scripting language". Then populate the initial variable context with a PicoContainer, and you need only a few lines of script to configure a non-standard component.
4) Option: don't care, just do it --------------------------------- The next trick is to make your container algorithm-agnostic. This looks a lot better in pico atm than anywhere else I've seen, but there's still room for some improvement :D. Encapsulate your policy into a factory class (rather than lots of metadata), the only 'metadata' you need to deploy the component is a reference to the factory class. With the factories similar to the ones in fortress, but with a little more responsibility.
A per-implementation-factory is a lot simpler to grasp and program than a per-deployment-profile-assembly.
You can have an AvalonFactory, a SpringframeworkFactory, a JythonFactory, and lots of different permutations.
/**
* @@jicarilla.atts.Component()
* @@jicarilla.atts.ComponentFactory(
* "com.leosimons.jicarilla.factories.SpringframeworkFactory" )
* @@jicarilla.atts.NamedInstance(
* new String[] { "my1", "my2", "my3" } )
*/
class MySpringFrameworkComponent implements MyComponent { /* ... */ }/**
* @@jicarilla.atts.Component()
* @@jicarilla.atts.ComponentFactory(
* "com.leosimons.jicarilla.factories.AvalonFactory" )
*/
class MyAvalonComponent implements MyComponent, ThreadSafe, Serviceable
{ /* ... */ }/**
* @@jicarilla.atts.Component()
* @@jicarilla.atts.ComponentFactory(
* "com.leosimons.jicarilla.factories.JythonFactory" )
* @@jicarilla.atts.jython.InitScript( "init.py" )
* @@jicarilla.atts.jython.DisposeScript( "dispose.py" )
*/
class MyScriptedComponent implements MyComponent { /* ... */ }More? ----- Demo of 1)-3) in my playground jicarilla.sf.net and associated wiki (disclaimer: the code is way too ugly to actually look at, but it serves as proof-of-concept). Springframework is at www.springframework.org. Testcase for the picocontainer factory setup (which, I've just found out, has been refactored) is @ http://cvs.codehaus.org/viewcvs.cgi/pico/src/test/org/picocontainer/defaults/DefaultPicoContainerWithComponentFactoryStringKeyTestCase.java?root=picocontainer
Currently working on an extended PicoContainer having various ComponentFactory implementations (stupid refactoring have to update to adapter now grmbl grmbl) for different lifecycles. That code is definately too ugly to look at though.
cheers,
- LSD
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
