You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Alfie Kirkpatrick <Al...@ioko.com> on 2009/07/14 14:43:01 UTC

Dynamic service binding based on symbol source

Hi, am trying to do something similar to that outlined in this thread...
http://markmail.org/thread/55zw3cg6n7zbfehn, but there was no firm
conclusion to it I can see.

 

I would like to instantiate a different service implementation depending
on property file configuration, eg. a stub for testing and a real
service for deployments. I'd like to put the FQN in my property file
which is then wrapped in a SymbolProvider.

 

My initial attempt looked like this:

 

                public static void bind(

                                                ServiceBinder binder,

                                                @Inject
@Symbol("myservice.fqn") Class<MyService> myserviceClass) {

                                binder.bind(ExcelFileImporter.class);

 
binder.bind(AvailableProgrammeProvider.class);

                                binder.bind(MyService.class,
myserviceClass);

                }

 

(I was kind of hoping that T5 would coerce from property file string to
class but doesn't matter if it won't)

 

Tapestry rejects this because bind() is not like contribute/build
methods and doesn't allow extra params.

 

I don't think a builder method is appropriate in my case -- while it
could use Class.forName from a property, I would not get any dependency
injection from the framework, and my stub vs. real service are likely to
have differing dependencies.

 

Any ideas? Would the pattern above be viable/useful as a feature
request? Am pretty sure I could make it work using system properties
rather than @Inject @Symbol, so feels like a reasonable thing to do.

 

For info I previously played around with per-build wiring using
additional modules and service overrides. While this works it's not very
elegant at all.

 

Thanks, Alfie.

 


RE: Dynamic service binding based on symbol source

Posted by Alfie Kirkpatrick <Al...@ioko.com>.
I managed to implement exactly what I wanted with a single additional
bind method overload on ServiceBinderImpl. As usual with Tapestry a fair
bit of head scratching but very little resulting work!

Have submitted with patch as an enhancement request. If anyone is
interested in the detail (or wants to vote for it), you can find it
here...

	https://issues.apache.org/jira/browse/TAP5-780

Regards, Alfie.

-----Original Message-----
From: Kristian Marinkovic [mailto:kristian.marinkovic@porsche.co.at] 
Sent: 15 July 2009 14:20
To: Tapestry users
Subject: Re: Dynamic service binding based on symbol source

hi Alfie,

i think i understand your problem....

in such situations i define a service with a dummy implementation. 
now another module can override the service with a correct
implementation.
its also useful to break up cyclic dependencies.

lets say if have a security module that provides a SubjectService.
because
the user data is managed by another module that itself depends on the 
security module i cannot have a SubjectService implementation within the
security module that loads the user data (using the user module
services). 

Instead i have a dummy implementation that throws an exception. only if 
the 
user module is deployed it will override this dummy implementation with
a 
proper 
one. (see ServiceOverride for more details)

in other circumstances i have a chain with a defined interface any other
module can contribute to. now when i build the services (builder method)
i delegate it to the chain and it will return the appropriate 
implementation.
so a chain element can decide to return a specific implementation if it 
needs to and stop the chain.

i hope this helps

g,
kris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Dynamic service binding based on symbol source

Posted by Kristian Marinkovic <kr...@porsche.co.at>.
hi Alfie,

i think i understand your problem....

in such situations i define a service with a dummy implementation. 
now another module can override the service with a correct implementation.
its also useful to break up cyclic dependencies.

lets say if have a security module that provides a SubjectService. because
the user data is managed by another module that itself depends on the 
security module i cannot have a SubjectService implementation within the
security module that loads the user data (using the user module services). 

Instead i have a dummy implementation that throws an exception. only if 
the 
user module is deployed it will override this dummy implementation with a 
proper 
one. (see ServiceOverride for more details)

in other circumstances i have a chain with a defined interface any other
module can contribute to. now when i build the services (builder method)
i delegate it to the chain and it will return the appropriate 
implementation.
so a chain element can decide to return a specific implementation if it 
needs to and stop the chain.

i hope this helps

g,
kris



"Thiago H. de Paula Figueiredo" <th...@gmail.com> 
15.07.2009 14:18
Bitte antworten an
"Tapestry users" <us...@tapestry.apache.org>


An
"Tapestry users" <us...@tapestry.apache.org>
Kopie

Thema
Re: Dynamic service binding based on symbol source







Why wouldn't a buildXXX() method injecting the symbol as a parameter and 
some ifs or switch statements work in your scenario?

-- 
Thiago H. de Paula Figueiredo
Independent Java consultant, developer, and instructor
http://www.arsmachina.com.br/thiago

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org



Re: Dynamic service binding based on symbol source

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Why wouldn't a buildXXX() method injecting the symbol as a parameter and  
some ifs or switch statements work in your scenario?

-- 
Thiago H. de Paula Figueiredo
Independent Java consultant, developer, and instructor
http://www.arsmachina.com.br/thiago

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


RE: Dynamic service binding based on symbol source

Posted by Alfie Kirkpatrick <Al...@ioko.com>.
Hi Massimo, thanks for the reply. Unfortunately neither of these
patterns works for me because they rely on the chained service(s) being
instantiated in the normal way, ie. via bind or build.

Looking at DefaultModuleDefImpl there doesn't seem any reason in
principle why it's too early in the bind() method of a module to late
bind an implementation class based on a symbol. Or alternatively have a
special form of buildXxxxx which supports this kind of thing, ie.
allowing the builder to return a service definition rather than a
concrete class via new. Am still looking through the sources to see what
might be possible/simple.

Unless I'm missing something I don't think what I'm after can be done
without a change to Tapestry. Anyone disagree? Do people think this is
this a reasonable feature request?

Regards, Alfie.

-----Original Message-----
From: Massimo Lusetti [mailto:mlusetti@gmail.com] 
Sent: 14 July 2009 13:47
To: Tapestry users
Subject: Re: Dynamic service binding based on symbol source

On Tue, Jul 14, 2009 at 2:43 PM, Alfie
Kirkpatrick<Al...@ioko.com> wrote:


> I would like to instantiate a different service implementation
depending
> on property file configuration, eg. a stub for testing and a real
> service for deployments. I'd like to put the FQN in my property file
> which is then wrapped in a SymbolProvider.

I highly suggest you to build a chain of command or a strategy pattern
depending on service type and let the IoC do the work for you.

-- 
Massimo
http://meridio.blogspot.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


RE: Dynamic service binding based on symbol source

Posted by Alfie Kirkpatrick <Al...@ioko.com>.
Hi Kris, thanks for the reply.

This would work but it's a bit messy and does give me the proper
separation of concern I'm after. One of the things I might want is to
have a stub implementation in test classes, or pulled in from another
module which only gets included under a certain maven profile, which
doesn't get packaged into my final app. Or taking it further, the
implementation class might even be outside the app in which case I don't
want my module to know anything about the implementation class at all.

The following code works perfectly for me, I just want to have it under
the control of SymbolSource rather than system properties!!

		String myServiceBuilderClass = System.getProperty(
				"my.servicebuilder",
	
"com.ioko.t5demo.ws.MyServiceStubBuilder");
		Class<MyServiceBuilder> clazz =
(Class<MyServiceBuilder>) Class
				.forName(myServiceBuilderClass);
		binder.bind(MyServiceBuilder.class, clazz);

Regards, Alfie.

-----Original Message-----
From: Kristian Marinkovic [mailto:kristian.marinkovic@porsche.co.at] 
Sent: 15 July 2009 11:31
To: Tapestry users
Subject: RE: Dynamic service binding based on symbol source

hi alfie,

i don't know if i'm missing something but you could
solve it this way:

public Service buildService(@Inject @Sysmbol("whatever") Long numeric, 
@InjectService("VariantA") Service serviceA, @InjectService("VariantB") 
Service serviceB)
{
    switch(numeric)
   {
        case 2: return serviceA;
        case 42: return serviceB;
        default:
        throw new Exception();
    }
}

if you want to use the Service without qualifier you 
could define another inteface for the variants

g,
kris




"Alfie Kirkpatrick" <Al...@ioko.com> 
15.07.2009 10:42
Bitte antworten an
"Tapestry users" <us...@tapestry.apache.org>


An
"Massimo Lusetti" <ml...@gmail.com>, "Tapestry users" 
<us...@tapestry.apache.org>
Kopie

Thema
RE: Dynamic service binding based on symbol source







Further to my last mail I think it could be possible to have a module
method convention like:

                 public static com.acme.service.MyService 
bindByConfiguration() {
                 }

This would look for a symbol "com.acme.service.MyService" based on the
return type and use a variant on the ConstructorServiceCreator to
instantiate the service.

Or perhaps a ServiceBinder.bind(MyService.class,
"the.symbol.name.for.impl.class") method would work. It seems a bit
tidier.

Either should be possible since ServiceBuilderMethodInvoker is able to
resolve symbols as parameters via
InternalUtils.calculateParametersForMethod. It's just that the current
code/encapsulation level isn't really geared for what I want to do -- I
need a bit of both ConstructorServiceCreator and
ServiceBuilderMethodInvoker. But I'll keep digging.

Regards, Alfie.

-----Original Message-----
From: Massimo Lusetti [mailto:mlusetti@gmail.com] 
Sent: 14 July 2009 13:47
To: Tapestry users
Subject: Re: Dynamic service binding based on symbol source

On Tue, Jul 14, 2009 at 2:43 PM, Alfie
Kirkpatrick<Al...@ioko.com> wrote:


> I would like to instantiate a different service implementation
depending
> on property file configuration, eg. a stub for testing and a real
> service for deployments. I'd like to put the FQN in my property file
> which is then wrapped in a SymbolProvider.

I highly suggest you to build a chain of command or a strategy pattern
depending on service type and let the IoC do the work for you.

-- 
Massimo
http://meridio.blogspot.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


RE: Dynamic service binding based on symbol source

Posted by Kristian Marinkovic <kr...@porsche.co.at>.
hi alfie,

i don't know if i'm missing something but you could
solve it this way:

public Service buildService(@Inject @Sysmbol("whatever") Long numeric, 
@InjectService("VariantA") Service serviceA, @InjectService("VariantB") 
Service serviceB)
{
    switch(numeric)
   {
        case 2: return serviceA;
        case 42: return serviceB;
        default:
        throw new Exception();
    }
}

if you want to use the Service without qualifier you 
could define another inteface for the variants

g,
kris




"Alfie Kirkpatrick" <Al...@ioko.com> 
15.07.2009 10:42
Bitte antworten an
"Tapestry users" <us...@tapestry.apache.org>


An
"Massimo Lusetti" <ml...@gmail.com>, "Tapestry users" 
<us...@tapestry.apache.org>
Kopie

Thema
RE: Dynamic service binding based on symbol source







Further to my last mail I think it could be possible to have a module
method convention like:

                 public static com.acme.service.MyService 
bindByConfiguration() {
                 }

This would look for a symbol "com.acme.service.MyService" based on the
return type and use a variant on the ConstructorServiceCreator to
instantiate the service.

Or perhaps a ServiceBinder.bind(MyService.class,
"the.symbol.name.for.impl.class") method would work. It seems a bit
tidier.

Either should be possible since ServiceBuilderMethodInvoker is able to
resolve symbols as parameters via
InternalUtils.calculateParametersForMethod. It's just that the current
code/encapsulation level isn't really geared for what I want to do -- I
need a bit of both ConstructorServiceCreator and
ServiceBuilderMethodInvoker. But I'll keep digging.

Regards, Alfie.

-----Original Message-----
From: Massimo Lusetti [mailto:mlusetti@gmail.com] 
Sent: 14 July 2009 13:47
To: Tapestry users
Subject: Re: Dynamic service binding based on symbol source

On Tue, Jul 14, 2009 at 2:43 PM, Alfie
Kirkpatrick<Al...@ioko.com> wrote:


> I would like to instantiate a different service implementation
depending
> on property file configuration, eg. a stub for testing and a real
> service for deployments. I'd like to put the FQN in my property file
> which is then wrapped in a SymbolProvider.

I highly suggest you to build a chain of command or a strategy pattern
depending on service type and let the IoC do the work for you.

-- 
Massimo
http://meridio.blogspot.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org



RE: Dynamic service binding based on symbol source

Posted by Alfie Kirkpatrick <Al...@ioko.com>.
Further to my last mail I think it could be possible to have a module
method convention like:

	public static com.acme.service.MyService bindByConfiguration() {
	}

This would look for a symbol "com.acme.service.MyService" based on the
return type and use a variant on the ConstructorServiceCreator to
instantiate the service.

Or perhaps a ServiceBinder.bind(MyService.class,
"the.symbol.name.for.impl.class") method would work. It seems a bit
tidier.

Either should be possible since ServiceBuilderMethodInvoker is able to
resolve symbols as parameters via
InternalUtils.calculateParametersForMethod. It's just that the current
code/encapsulation level isn't really geared for what I want to do -- I
need a bit of both ConstructorServiceCreator and
ServiceBuilderMethodInvoker. But I'll keep digging.

Regards, Alfie.

-----Original Message-----
From: Massimo Lusetti [mailto:mlusetti@gmail.com] 
Sent: 14 July 2009 13:47
To: Tapestry users
Subject: Re: Dynamic service binding based on symbol source

On Tue, Jul 14, 2009 at 2:43 PM, Alfie
Kirkpatrick<Al...@ioko.com> wrote:


> I would like to instantiate a different service implementation
depending
> on property file configuration, eg. a stub for testing and a real
> service for deployments. I'd like to put the FQN in my property file
> which is then wrapped in a SymbolProvider.

I highly suggest you to build a chain of command or a strategy pattern
depending on service type and let the IoC do the work for you.

-- 
Massimo
http://meridio.blogspot.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Dynamic service binding based on symbol source

Posted by Massimo Lusetti <ml...@gmail.com>.
On Tue, Jul 14, 2009 at 2:43 PM, Alfie
Kirkpatrick<Al...@ioko.com> wrote:


> I would like to instantiate a different service implementation depending
> on property file configuration, eg. a stub for testing and a real
> service for deployments. I'd like to put the FQN in my property file
> which is then wrapped in a SymbolProvider.

I highly suggest you to build a chain of command or a strategy pattern
depending on service type and let the IoC do the work for you.

-- 
Massimo
http://meridio.blogspot.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org