Hi Simon, Hi All,
See comments inline.
Thx, Eric

On 11/01/2013 08:24, Simone Tripodi wrote:
The topic here is not binding multiple version of the same service -
that Guice would already allow out of the box anyway, via binding
annotations


Well, not really versions of the same implementation, but different implementations.

OSGI can a bit further and defines different version of the same implementation.

The main issue is enabling the SPI module - services automatically
discovered via the "ServiceLoader" pattern - to qualify discovered
bindings.

@(com.google.inject.name|javax.inject).Named is just *one* way to
qualify bindings, this is why IMHO supporting a more complete set of
metadata (Properties versus @Named) would help users specify more
accurate qualifications.

The "version" in my sample was just fake data - "version" is indeed a
string value, not an hardcoded key in the annotations - to show how to
express multiple properties.


You mean the version attribute of your example can be statically loaded from a properties file for example?

@Property.List({
    @Property( name="type", value="Visa" ),
    @Property( name="version", value=VisaVersion.VERSION )
})

I guess the example you gave with the version is not about loading different version of a same implementation, but just defining which concrete implementation to choose.


So, my question is: would a single @Named binding annotation enough
for users to qualify their bindings?

TIA,
-Simo

http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/


On Thu, Jan 10, 2013 at 10:16 PM, Christoph Engelbert
<[email protected]> wrote:
I would use OSGi when I need multiple version of the same service. I
don't think that I would use a DI framework with explicitly declared
version information.

Chris

Am 10.01.2013 21:51, schrieb Simone Tripodi:
Hi all guys,

I think the main idea of services binding[1] in SPI is good but still
a little far to be complete, because what they miss are *qualifiers*,
I mean, Guice allows binding the same interface/service to multiple
instances by qualifying them via annotations, i.e.

bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
bind(CreditCardProcessor.class).annotatedWith(Names.named("Mastercard")).to(MastercardCreditCardProcessor.class);

So users can require service injection depending on bound metadata,
rather than requiring and explicit class implementation:

@Inject
@Named("Visa")
CreditCardProcessor creditCardProcessor;

Now, coming back to the current SPI implementation, it just allows
doing silly bindings, such as bind the service to the first discovered
implementation or getting all the discovered implementations, mainly
because META-INF/services files just enlist service implementation,
i.e.

file META-INF/services/org.acme.CreditCardProcessor
-----------------------------------------------------------------
org.acme.VisaCreditCardProcessor
org.acme.MastercardCreditCardProcessor

There are not qualifiers :( While at the time of coding the first
version of SPI it made me happy, now I am not longer satisfied.

We can do something better, my proposal is:

* allows specifying a set of metadata - please remind that qualifiers,
binding annotations, can be more complex rather than just @Named - in
META-INF/services files for each service, something like

file META-INF/services/org.acme.CreditCardProcessor
-----------------------------------------------------------------
org.acme.VisaCreditCardProcessor; type=Visa; version=1.0.0;
org.acme.MastercardCreditCardProcessor; type=Mastercard; version=1.5.0;

* defining a new binding annotation, something like:

@Documented
@Retention( RetentionPolicy.RUNTIME )
public @interface Property
{

     String name();

     String value();

     @Documented
     @BindingAnnotation
     @Retention( RetentionPolicy.RUNTIME )
     @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
     @interface List
     {
         Property[] value();
     }

}

in order users can request injections specifying injections like:

@Inject
@Property.List({
     @Property( name="type", value="Visa" ),
     @Property( name="version", value="1.0.0" )
})
CreditCardProcessor creditCardProcessor;

WDYT? Do you have any idea?
Many thanks in advance!
-Simo

[1] http://onami.incubator.apache.org/spi/services.html

http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/

Reply via email to