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