Hello,
I would like to add a few thoughts to this discussion.
I am currently trying to use HiveMind in client (Swing GUI application) and
in the current status (HM1.0, but HM1.1a1 would not bring much to me now), I
found the need for a "PojoFactory", but with needs wider than the ones you
describe.
In particular, I don't need "one-time" objects, but rather need a real
"factory" able to build several instances of the same pojo according to the
same configuration. The number of instances to create is never known in
advance (each instance can be a JPanel, a JTable...)
I finished building my own "ObjectBuilder" service (I would have preferred
"BeanFactory"...) with a very simple interface:
Object create(String name);
And a quite simple configuration (I did not try to reproduce the exact same
features as BuilderFactory, in particular I did not want/need auto-wiring):
<contribution configuration-id="ObjectBuilderObjects">
<object name="MyName" class=" MyClass">
<inject object="service:EventDispatcher"/>
</object>
<object name="OtherName" class="OtherClass">
<inject name="myProperty" object="object:MyName"/>
</object>
</contribution>
The contributions are quite simple since they reuse the "object" translator
and thus can inject:
- services
- configurations
- instances
- beans
- ...
Both constructor and setter injections are supported (if the "name"
attribute is defined then setter-injection is used).
I also added a new ObjectProvider (called "object:") so that other pojos can
be injected also (both in pojos and in services).
It would easily be possible to add new configuration settings so that a name
defines a unique instance (in cases where this would be necessary).
The first version I wrote was a breeze, thanks to HiveMind PropertyUtils and
ConstructorUtils.
Then very quick I discovered problems while using the ObjectTranslator: it
is only evaluated once and very early (as soon as the "ObjectBuilderObjects"
is read by the ObjectBuilder service). This involved two problems:
- all injections (pojos, beans, services, configs...) are instantiated at
the beginning of the application, even if the objects that use these
injections are never used!
- early evaluation could induce recursive calls inside HM (eg: inject a
configuration that itself uses the "object:" ObjectProvider)
So my second version added late evaluation of all injections: for this I
just passed the "object" attribute value as a String (ie, I did not use the
ObjectTranslator anymore at the configuration level). Then the ObjectBuilder
service itself would resolve all injections (by calling the ObjectTranslator
directly, which will be a problem in HM1.1 since the ObjectTranslator has
now private visibility).
Finally, my current version (maybe not the last one however) added the
possibility to inject constructor arguments directly through a new
ObjectBuilder.create(String name, Object[] args) method. In the config, I
just added a new <inject-arg/> empty element to indicate this fact.
This can be used, for instance, to build a JPanel subclass instance, with
some injected services (always the same) plus an additional parameter like
the DTO to show in the panel (which is always different and cannot be
statically configured).
I don't know if I am off-topic here, but I wanted to express my viewpoint
that a new <bean> element to define _individual_ pojos does not seem
interesting to me (I much prefer the service concept with interfaces). What
seems really interesting to me is to have the possibility to create several
instances of one class, with some injected args, and some user-passed args.
I am not sure this would be much useful on the server side, but for sure it
could bring much on the client GUI side (when I have finished my
ObjectBuilder, it eased a lot about adding new panels, new tables... in my
GUI).
Cheers
Jean-Francois
-----Original Message-----
From: Howard Lewis Ship [mailto:[EMAIL PROTECTED]
Sent: Monday, February 07, 2005 1:54 AM
To: [email protected]
Subject: <bean> element
Part of this has been discussed on the wiki:
http://wiki.apache.org/jakarta-hivemind/PojoServices
People chafe at the use of interfaces for one-time use objects, but
still want all the dependency injection that BuilderFactory provides.
Adding a new <bean> element would solve a fair amount of this.
It wouldn't be quite inline, it might be more like:
<set-object property="databaseAccess" value="bean:DatabaseAccess"/>
...
<bean id="DatabaseAccess">
<construct class="mypackage.DatabaseAccess">
<set-object property="daoService" value="service:DAOService"/>
</construct>
</bean>
In this way, beans would be another namespace like services and
configurations, could have visibility, etc.
I think we could also dress up the instance: object provider to do
some *simple* configuration of the object, i.e.:
instance:mypackage.MyClass,booleanProperty=true,numericProperty=30,stringPro
perty='some
string'
You can already do some of this using hivemind.lib.BeanFactory.
On Sun, 6 Feb 2005 10:14:37 -0500, James Carman
<[EMAIL PROTECTED]> wrote:
> Knut,
>
> Maybe. But, is it really necessary to have to place them at the
top-level,
> especially if they're going to be used just one time? I guess I'd have to
> see an example descriptor file. Maybe I don't quite get what you guys are
> talking about.
>
> James
>
> -----Original Message-----
> From: Knut Wannheden [mailto:[EMAIL PROTECTED]
> Sent: Sunday, February 06, 2005 10:12 AM
> To: HiveMind Dev List; James Carman
> Subject: Re: AOPAlliance Service Interceptors...
>
> James,
>
> On Sun, 6 Feb 2005 09:44:47 -0500, James Carman
> <[EMAIL PROTECTED]> wrote:
> >
> > Well, I think if we're going to do this (generic, dependency injection
> > capable object builder), we should do it the right way. As soon as we
> > implement an object provider with this limited capability and no
> > work-around, someone is going to ask for an improvement. Then, we're
> going
> > to end up trying to encode dependency information (like what service-id
to
> > use when there are multiple services of the property type) into the
> "locator
> > string." What I would like to do would be something like this...
> >
> > <invoke-factory service-id="hivemind.BuilderFactory">
> > <construct class="myco.services.impl.MyServiceImpl">
> > <set-object property="a">
> > <construct class="myco.helpers.A" />
> > </set-object>
> > <set-object property="b">
> > <construct class="myco.helpers.B">
> > <set-service property="c" service-id="mymodule.A" />
> > </construct>
> > </set-object>
> > </construct>
> > </invoke-factory>
> >
> > Maybe we should let object providers provide a schema of their own.
> > Wouldn't that do the trick?
> >
>
> Wouldn't Howard's proposed top-level <bean> and the bean: object
> provider solve this? I find that easier to grasp :-)
>
> --knut
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
--
Howard M. Lewis Ship
Independent J2EE / Open-Source Java Consultant
Creator, Jakarta Tapestry
Creator, Jakarta HiveMind
Professional Tapestry training, mentoring, support
and project work. http://howardlewisship.com
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]