You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Marcus Crafter <cr...@managesoft.com> on 2003/07/25 16:57:10 UTC

[RT] Parameterized Lookups ?

Hi All,

Hope all is well!

We all know that Avalon has super cool lifecycle management offering a way 
to construct arbitrary components in defined manner. One limitation by 
this though is the requirement of a zero argument constructor.

This requirement is ok for many components but sometimes I miss this
especially when writing components that need some external data dynamically
before they can be considered valid.

For the lack of a better example, think of a Date component that needs
to be given a real date value before it can be used. Outside of Avalon one
might write:

MyDate date = new MyDate("20030607");

When using Avalon however, after creation through the normal lifecycle we 
must set the date on the component with some set* method.

MyDate date = (MyDate) m_manager.lookup(MyDate.ROLE);
date.setDate("20030725");

This means however that the component is not valid though until an external
(meaning non-lifecycle method) has been invoked on it, which we can't
enforce -> meaning we have to document somewhere that a user must
call the set* before calling any other method. 

It also means, if we're being proactive that in all of the other methods we 
have to watch for the case when the user doesn't invoke the set* method, 
and throw an appropriate exception, etc.

A possible way to fix this could be to offer Parameterized lookups, 
something like:

interface ServiceManager {

	Object lookup(String role, Object[] parameters);
}

where 'parameters' specifies arbitrary number of parameters that can be 
passed through to the component manager and given to the object to be 
constructed somehow (eg. lifecycle extension, matching parameter constructor, 
component handler, new lifecycle stage, etc).

This would let us do something like:

MyDate today = (MyDate) m_manager.lookup(MyDate.ROLE, { "20030725" } );

Thoughts anyone? Perhaps there's an even better solution out there ?

Cheers,

Marcus

-- 
        .....
     ,,$$$$$$$$$,      Marcus Crafter
    ;$'      '$$$$:    Computer Systems Engineer
    $:         $$$$:   ManageSoft GmbH
     $       o_)$$$:   82-84 Mainzer Landstrasse
     ;$,    _/\ &&:'   60327 Frankfurt Germany
       '     /( &&&
           \_&&&&'
          &&&&.
    &&&&&&&:

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


Re: [RT] Parameterized Lookups ?

Posted by Leo Simons <le...@apache.org>.
Marcus Crafter wrote:
> If I used a lifecycle extension to set the transaction configuration though, 
> do you think it would still be possible to set the configuration 
> dynamically from data built at runtime?? 

sure. But transaction support is, to say the least, "nontrivial" to do. 
Which is probably why it hasn't been done for avalon (open source, that is).

> Thanks again.

cheers!

- Leo



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


Re: [RT] Parameterized Lookups ?

Posted by Marcus Crafter <cr...@managesoft.com>.
Hi Leo,

Hope you enjoyed your holidays. :)

Thanks for taking the time to list some alternative approaches!

On Mon, Jul 28, 2003 at 10:49:20AM +0200, Leo Simons wrote:
> 
> think of seperating various types of constructor arguments for your comp 
> into the comp configuration, the comp dependencies, etc etc. The URI is 
> logically part of the client component configuration, right? Jason van 
> Zyl did this in plexus with the Configurator pattern:
> 
> interface ServiceBroker extends ServiceManager
> {
> 	Object lookup( String role, Configuration configuration );
> }

Interesting approach - I remember when Jason was talking about dynamic
reconfiguration of components. This must be how he achieved this.

> the easy way out is to not make everything into an avalon component, but 
> have an avalon component provide you with the worker class:
> 
> interface MyComponentManager
> {
> 	String ROLE = MyComponentManager.class.getName();
> 	Component newInstance( String URI );
> }
> 
> mcm = (MyComponentManager)m_sm.lookup( MyComponentManager.ROLE );
> component = mcm.newInstance( m_configuration
> 	.getchild( "component-uri" ).getValue() );

This probably suits my application the best - I should have realized this 
sooner as it's similar to the approach the SourceFactories use to create 
Source objects.

In my app though the URI is created dynamically - hence the need to set it
dynamically, but that could still work with the above of course.

> the clean way out is probably to use a lifecycle extension to decorate 
> your component with transaction support and make the client component 
> configuration part of the transaction state.

I think this is also what Leo Sutic was describing in another reply to my
email. It seems to be similar to the initial interface I had in that I have 
to set the URI via a set* method, but I like the use of ThreadLocals to 
essentially remove the need for Factory components - brilliant :)

If I used a lifecycle extension to set the transaction configuration though, 
do you think it would still be possible to set the configuration 
dynamically from data built at runtime?? 

Thanks again.

Cheers,

Marcus

-- 
        .....
     ,,$$$$$$$$$,      Marcus Crafter
    ;$'      '$$$$:    Computer Systems Engineer
    $:         $$$$:   ManageSoft GmbH
     $       o_)$$$:   82-84 Mainzer Landstrasse
     ;$,    _/\ &&:'   60327 Frankfurt Germany
       '     /( &&&
           \_&&&&'
          &&&&.
    &&&&&&&:

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


Re: [RT] Parameterized Lookups ?

Posted by Marcus Crafter <cr...@managesoft.com>.
Hi All, esp. the Leo's! :)

Thanks guys for widing my perspectives on how to create components within 
Avalon :)

I'll give the various approaches a go and see which one works best in my
particular application.

Cheers,

Marcus

On Mon, Jul 28, 2003 at 10:49:20AM +0200, Leo Simons wrote:
> Marcus Crafter wrote:
> >On Fri, Jul 25, 2003 at 11:09:46AM -0400, Berin Loritsch wrote:
> >
> >Currently I have a component requires a URI location to work, it has
> >4 or so methods in it's interface, each of them need the remote URI 
> >location
> >for the methods to work. At the moment I specify the URI location 
> >as a parameter to each method, something like:
> >
> >interface Component {
> >
> >	void doOp1(URI uri);
> >	void doOp2(URI uri);
> >	void doOp3(URI uri);
> >	void dpOp4(URI uri);
> >}
> >
> >Ideally I'd like to be able to specify the URI once, and then be able to 
> >call the methods, outside of Avalon you'd do something like:
> >
> >Component c = new Component("http://host/location/");
> >c.doOp1();
> >....
> >c.doOp2();
> >
> >as a constructor parameter.
> 
> think of seperating various types of constructor arguments for your comp 
> into the comp configuration, the comp dependencies, etc etc. The URI is 
> logically part of the client component configuration, right? Jason van 
> Zyl did this in plexus with the Configurator pattern:
> 
> interface ServiceBroker extends ServiceManager
> {
> 	Object lookup( String role, Configuration configuration );
> }
> 
> the easy way out is to not make everything into an avalon component, but 
> have an avalon component provide you with the worker class:
> 
> interface MyComponentManager
> {
> 	String ROLE = MyComponentManager.class.getName();
> 	Component newInstance( String URI );
> }
> 
> mcm = (MyComponentManager)m_sm.lookup( MyComponentManager.ROLE );
> component = mcm.newInstance( m_configuration
> 	.getchild( "component-uri" ).getValue() );
> 
> the clean way out is probably to use a lifecycle extension to decorate 
> your component with transaction support and make the client component 
> configuration part of the transaction state.
> 
> 
> cheers!
> 
> 
> - Leo
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
> For additional commands, e-mail: dev-help@avalon.apache.org

-- 
        .....
     ,,$$$$$$$$$,      Marcus Crafter
    ;$'      '$$$$:    Computer Systems Engineer
    $:         $$$$:   ManageSoft GmbH
     $       o_)$$$:   82-84 Mainzer Landstrasse
     ;$,    _/\ &&:'   60327 Frankfurt Germany
       '     /( &&&
           \_&&&&'
          &&&&.
    &&&&&&&:

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


Re: [RT] Parameterized Lookups ?

Posted by Leo Simons <le...@apache.org>.
Marcus Crafter wrote:
> On Fri, Jul 25, 2003 at 11:09:46AM -0400, Berin Loritsch wrote:
 >
> Currently I have a component requires a URI location to work, it has
> 4 or so methods in it's interface, each of them need the remote URI location
> for the methods to work. At the moment I specify the URI location 
> as a parameter to each method, something like:
> 
> interface Component {
> 
> 	void doOp1(URI uri);
> 	void doOp2(URI uri);
> 	void doOp3(URI uri);
> 	void dpOp4(URI uri);
> }
> 
> Ideally I'd like to be able to specify the URI once, and then be able to call 
> the methods, outside of Avalon you'd do something like:
> 
> Component c = new Component("http://host/location/");
> c.doOp1();
> ....
> c.doOp2();
> 
> as a constructor parameter.

think of seperating various types of constructor arguments for your comp 
into the comp configuration, the comp dependencies, etc etc. The URI is 
logically part of the client component configuration, right? Jason van 
Zyl did this in plexus with the Configurator pattern:

interface ServiceBroker extends ServiceManager
{
	Object lookup( String role, Configuration configuration );
}

the easy way out is to not make everything into an avalon component, but 
have an avalon component provide you with the worker class:

interface MyComponentManager
{
	String ROLE = MyComponentManager.class.getName();
	Component newInstance( String URI );
}

mcm = (MyComponentManager)m_sm.lookup( MyComponentManager.ROLE );
component = mcm.newInstance( m_configuration
	.getchild( "component-uri" ).getValue() );

the clean way out is probably to use a lifecycle extension to decorate 
your component with transaction support and make the client component 
configuration part of the transaction state.


cheers!


- Leo



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


Re: [RT] Parameterized Lookups ?

Posted by Marcus Crafter <cr...@managesoft.com>.
On Fri, Jul 25, 2003 at 11:09:46AM -0400, Berin Loritsch wrote:
> Perhaps if I have a better understanding of the real problem you are trying
> to solve, I might be able to better grasp what you are getting at.  For
> instance, I can think of some things that would make sense for a container
> to pass into a component on lookup but I have trouble in my mind coming up
> with a reason to pass user variables to the component.

Ok. Currently I have a component requires a URI location to work, it has
4 or so methods in it's interface, each of them need the remote URI location
for the methods to work. At the moment I specify the URI location 
as a parameter to each method, something like:

interface Component {

	void doOp1(URI uri);
	void doOp2(URI uri);
	void doOp3(URI uri);
	void dpOp4(URI uri);
}

Ideally I'd like to be able to specify the URI once, and then be able to call 
the methods, outside of Avalon you'd do something like:

Component c = new Component("http://host/location/");
c.doOp1();
...
c.doOp2();

as a constructor parameter.

Inside of Avalon, as far as I can tell, to do this I need to add a setter
method to set the URI:

interface Component {

	setURI(URI uri);

	void doOp1();
	void doOp2();
	void doOp3();
	void dpOp4();
}

But I don't really like this too much, because setURI() needs to be called
to make the component valid. I need to check in each operation that the URI
has been set if a user of this component forgets to set it, etc, etc.

What I'd like to be able to do, is specify the URI when the component
is looked up, so that I can be sure that the component is valid when the 
user gets a reference to it.

Perhaps parameterizing the lookup is the wrong approach - but hopefully that
gives you a better understanding of what I'm trying to do.

> Keep in mind that components might be shared across instances, so what it
> looks like you are proposing won't work for them.  Also, I would like to
> know the scope of the parameter.  Does it apply as long as the client 
> maintains
> its reference to the component, so that after the component is released the
> parameter is null and void?

Honestly I hadn't thought about the scope of the parameter, with my container
I would be setting the parameter to be the internal URI reference which
would mean it would exist until the component is decomissioned.

But, since it's an RT, we can change the solution to be however we like! :)

> Solving real problems is what will keep Avalon Framework lean and mean.  I
> think we should resist changes to Avalon Framework unless there is a well
> defined reason to do so, and all the committers agree.  So we need to 
> compare
> a real life example showing why it is cumbersome to do it now, and how much
> easier it will be in the future if we adopt the proposal.

Sure, I agree we should keep the interfaces lean and mean. If this solution
is not the best, perhaps there's a better solution to the problem that we 
might discover ?

Cheers,

Marcus

-- 
        .....
     ,,$$$$$$$$$,      Marcus Crafter
    ;$'      '$$$$:    Computer Systems Engineer
    $:         $$$$:   ManageSoft GmbH
     $       o_)$$$:   82-84 Mainzer Landstrasse
     ;$,    _/\ &&:'   60327 Frankfurt Germany
       '     /( &&&
           \_&&&&'
          &&&&.
    &&&&&&&:

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


Re: [RT] Parameterized Lookups ?

Posted by Berin Loritsch <bl...@apache.org>.
Perhaps if I have a better understanding of the real problem you are trying
to solve, I might be able to better grasp what you are getting at.  For
instance, I can think of some things that would make sense for a container
to pass into a component on lookup but I have trouble in my mind coming up
with a reason to pass user variables to the component.

Keep in mind that components might be shared across instances, so what it
looks like you are proposing won't work for them.  Also, I would like to
know the scope of the parameter.  Does it apply as long as the client maintains
its reference to the component, so that after the component is released the
parameter is null and void?

Solving real problems is what will keep Avalon Framework lean and mean.  I
think we should resist changes to Avalon Framework unless there is a well
defined reason to do so, and all the committers agree.  So we need to compare
a real life example showing why it is cumbersome to do it now, and how much
easier it will be in the future if we adopt the proposal.

Marcus Crafter wrote:

> Hi All,
> 
> Hope all is well!
> 
> We all know that Avalon has super cool lifecycle management offering a way 
> to construct arbitrary components in defined manner. One limitation by 
> this though is the requirement of a zero argument constructor.
> 
> This requirement is ok for many components but sometimes I miss this
> especially when writing components that need some external data dynamically
> before they can be considered valid.
> 
> For the lack of a better example, think of a Date component that needs
> to be given a real date value before it can be used. Outside of Avalon one
> might write:
> 
> MyDate date = new MyDate("20030607");
> 
> When using Avalon however, after creation through the normal lifecycle we 
> must set the date on the component with some set* method.
> 
> MyDate date = (MyDate) m_manager.lookup(MyDate.ROLE);
> date.setDate("20030725");
> 
> This means however that the component is not valid though until an external
> (meaning non-lifecycle method) has been invoked on it, which we can't
> enforce -> meaning we have to document somewhere that a user must
> call the set* before calling any other method. 
> 
> It also means, if we're being proactive that in all of the other methods we 
> have to watch for the case when the user doesn't invoke the set* method, 
> and throw an appropriate exception, etc.
> 
> A possible way to fix this could be to offer Parameterized lookups, 
> something like:
> 
> interface ServiceManager {
> 
> 	Object lookup(String role, Object[] parameters);
> }
> 
> where 'parameters' specifies arbitrary number of parameters that can be 
> passed through to the component manager and given to the object to be 
> constructed somehow (eg. lifecycle extension, matching parameter constructor, 
> component handler, new lifecycle stage, etc).
> 
> This would let us do something like:
> 
> MyDate today = (MyDate) m_manager.lookup(MyDate.ROLE, { "20030725" } );
> 
> Thoughts anyone? Perhaps there's an even better solution out there ?
> 
> Cheers,
> 
> Marcus
> 


-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


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