Re: [picocontainer-dev] patches for *full* binding-annotation capability - key take aways & thoughts

Paul Hammant <[email protected]>
Newsgroups gmane.comp.java.picocontainer.devel
Message-ID <[email protected]>
The style of binding annotations is like so -

     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.FIELD, ElementType.PARAMETER})
     @Bind
     public static @interface BindOne {}

You'll make one of these per place where dis-ambiguation is needed.   
@Bind is marking this annotation as being one that can be used for  
dependency-injection binding (its in Pico's codebase, whereas BindOne  
will be in the customer's codebase)

You can drop either of ElementType.FIELD or ElementType.PARAMETER  
depending on which flavor of DI you are doing.

Unfortunately there's no way to do the much more terse (maybe in JDK  
9.0) -

    public @interface BindOne extends Bind { }

---

I've got binding annotations working for :

   * Constructor Injection
   * Setter Injection
   * Field Injection
   * Method Injection

---

It has required changes to the PicoContainer interface :-


Clearly there is some ugliness there - getComponentAdapter(s) has two  
two-arg varients that in many of the test cases I've had to please  
the compiler by casting null to ParameterName.

it might be better to have a single signature for each -

      <T> ComponentAdapter<T> getComponentAdapter(Class<T>  
componentType, Object... bindingHint);

- where binding hint could be a) missing, b) a ParameterName instance  
or c) a binding annotation.  Unfortunately there's no abstraction  
that can fit both and an Object varargs is hardly elegant.

(see later for other alternates)

---

Note also that  "Class<? extends Annotation>" is the way of referring  
to a binding annotation outside of its instance. Lemme explain -  
BindOne.class is how you're refer to an annotation outside of its use  
as an annotation (next to a parameter or field in our case).   
Annotation is what reflection hands you when you're asking a Field  
what its annotation(s) are.  That's an instance of an annotation even  
though it 'feels' like part of a definition. That's living in  
reflection-world I guess.  From the annotation instance, you can go  
back to the defining class by invoking annotationType() on the  
instance.  The way were doing binding annotations in this patch means  
that there is no useful instance data for the annotation (strong  
typing is what you after on its own).  The last patch talked of Bind 
(id = "hello") and alike.  That's not what one is after if one is  
going down the annotations road.

---

Alternate ideas -

      <T> ComponentAdapter<T> getComponentAdapterWithBinding(Class<T>  
componentType, Class<? extends Annotation> binding);
      <T> T getComponentWithBinding(Class<T> componentType, Class<?  
extends Annotation> binding);

      <T> ComponentAdapter<T> getComponentAdapter(Key<T> key);
      <T> T getComponent(Key<T> key);

           - Key could be a wrapper for Class on its own, or Class &  
binding annotation together.

Or even a more fluent style - (usage example) -

      Apple appleOne = mpc.forBoundAnnotation 
(BindOne.class).getComponentAdapter(Apple.class);

Which hints at a more fluent addComponent() styles -

      mpc.addComponent(Apple.class, AppleImpl1.class).withBindingTo 
(BindOne.class);

      mpc.forBindingTo(BindOne.class).addComponent(Apple.class,  
AppleImpl1.class);

Thoughts?

- Paul

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email
pastedGraphic.tiff (image/tiff, 33.5 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.