Date: 2004-06-24T06:37:16
   Editor: 200.69.248.193 <>
   Wiki: Jakarta HiveMind Wiki
   Page: InjectingNonServiceFactoryObtainedObjects
   URL: 
http://wiki.apache.org/jakarta-hivemind/InjectingNonServiceFactoryObtainedObjects

   no comment

New Page:

= Q.  Injecting Non-Service Factory Obtained Objects =
''(DanielFeist 21/06/2004)''  


''(Maybe this is a ChangeProposal rather than a question.  That depends on the 
answer  ...  lets wait and see and possibly move it is it doesn't belong here)''

Is there anyway to inject a service, using the BuilderFactory, with an object 
obtained by invoking a method of another service.  I can think of many cases 
were this would be very useful but it doesn't seem to be possible.  Concrete 
examples are as follows:

''Example 1'':  I have a Mailer service which depends on, and uses, a 
datasource to obtain email address.  This datasource is to be obtained via JNDI 
so i decide to use the NameLookup service to obtain the datasource.  As the 
datasource is not a service but rather the result from executing a lookup 
method of a service it seems i am limited from injecting it into my Mailer 
service through declarative configuration in the hivemodule.sdl.

''Example 2'':  I have a Mailer service which uses a Properties to obtain email 
address.  The backing store of the properties has to be flexible and 
configurable so i decide to create a !PropertyFactory service that returns a 
Properties object for a given locator and whose backing store is defined and 
configured through a configuration point.  This is a good solution to my 
problem but as in example 1 I cannot inject this properties into my Mailer 
Service.

On a side note: If this type of injection is possible then a clean solution to 
my change proposal ModuleResourcesProposal is very simple.   Resources would be 
created using a factory specifically designed to do this (much like the 
BeanFactory) which would also manage backing-store type and synchronization 
issues.  These resources could then be injected into services by using 
!ResourceFactory's get method to obtain the resource.

----

HowardLewisShip: Seems that !BuilderFactory could do this, by changing the 
nested {{{set-service}}} element to have an additional attribute,
{{{read-property}}} that would be a property of the service to read as the 
value to assign to the service implementation under construction.  Perhaps 
{{{set-service}}} should be left alone, and there should be a 
{{{read-service-property}}} element added instead.

----

DanielFeist:  
What we are actually want to set here (in order to accomplish what is explained 
in the examples above) is not as you mentioned the property of another service 
(i.e. allowing the copying properties between servcies) BUT rather the value 
obtained from invoking a method of another service.  Something like the 
following would be needed as a nested BuilderFactory element in order to set a 
property of the service in construction with an object (in this case a 
datasource) obtained from another factory/lookup service:

{{{
set-service-method-return-value (property=datasource 
service-id=hivemind.lib.NameLookup method=lookup){
  argument{
    java:/jdbc/myDS
  }
  argument (translator=class)
    javax.sql.DataSource
  }
}
}}}.

Obviosly the name i have put 'set-service-method-return-value' is rather long 
and would need to be improved.  I've put that name in the example so it is 
clear what in fact the functionality is.

HowardLewisShip: Going down this path, you quickly get to the point where you 
want to use ["OGNL"] for this ... or a full scripting language. I don't have an 
objection to that as an add-on, but don't think it is right for the core 
module. The fact that you can add this (by creating your own service 
implementation factory) is good enough.

DanielFeist: What about including just the basics of this functionality in the 
core module?  I am keen on seeing this available to be able to do such simple 
things such as inject an object obtained from the BeanFactory or similair 
without the complexity of having to implement and define your own service 
implementation factory.  For more complex situations, where more than one 
String attribute is required yes its fair enough to have extend the 
BuilderFactory.

{{{
set-service-method-value (property=myBean service-id=my.lib.MyFactory 
method=get argument=myBean)}
}}}

The addition of this functionality to the BulderFactory doesn't actually 
require changes to the core module implementation but rather just the addition 
of an element in the BuilderFactory schema definition and a translator.  Is 
there anyway of extending BuilderFactory's schema defined in core hivemind 
module?

HowardLewisShip: I think there may be a proposal about making it easier to 
reuse and extend portions of a schema.  !BuilderFactory's parameter's schema is 
massively complex.

An OGNL builder parameter element might look something like:

{{{
set-expression (property=datasource expression=<<
  service["hivemind.lib.NameLookup"].lookup("java:/jdbc/myDS")
>>)
}}}

This would imply a magic {{{service}}} property attached to {{{Module}}} that 
could invoke {{{getService(String,Class)}}}.  I may end up building something 
like this for Tapestry, since Tapestry already has an OGNL dependency.

DanielFeist: What then, in terms of !HiveMind 1.0 (assuming no OGNL) is the 
solution to the simple problem put forward in the two initial examples?  
Implement and define in sdl my own !CustomBuilderFactory (the implementation of 
builder factory would be identical but with a slightly more complex schema)?  
There's no simpler solution?  I think considering OGNL or something similar to 
make builder paramenters simpler and more flexible for the next version is a 
good move.

HowardLewisShip: A completely reasonable and testable solution is to assign the 
service (i.e. {{{hivemind.lib.NameLookup}}} to a property of your service, and 
use the {{{initialize-method}}} attribute to have your service initialize.  In 
Java code, you can access the methods of the collaborating services.

DanielFeist: Yes that's a good workable solution the downside it that its not 
100% IOC i.e. the !DataSource is not being injected but rather work has to be 
done in the services init method to obtian the datasource.  In !HiveMinds 
current state that is the best solution I suppose.  I do believe though that 
the ability to be able to inject other objects that are not services or 
configurations (obtained from a lookup/factory service) is an important 
functionality that should certainly be considered as not everything we might 
want to use and inject can or should de represented as a service.

DanielFeist:  I've just been looking at the BeanFactory and translator and it 
would seem that you have actually started implementation of something that 
allows the us to obtain objects from a factory.  The PiplineFactoryService, for 
example uses, in its configuration contributions, beans obtained from the 
BeanFactory.  This is good and works well for the needs of the 
PipelineFactoryService configuration but it would be far more flexible to be 
able to obtain an object from any POJOF (plain old java object facotry) and not 
just from a BeanFactory.  Is there anyway of doing the same sort of thing but 
allowing the use of arbitary user implemented factories (not neccessarly 
implementing BeanFactory)?  Maybe it would be possible to extend the 
!ObjectTranslator or !BeanTranslator to do this.

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

Reply via email to