+1 On Thu, Apr 8, 2010 at 15:42, Vincent Massol <[email protected]> wrote:
On Apr 8, 2010, at 3:17 PM, Sergiu Dumitriu wrote:
On 04/08/2010 02:21 PM, Vincent Massol wrote:
Hi devs,
Since the JSR330 is now accepted as final and thus as a standard, I'd like to propose that we modify our component annotations to use it.
+1
Rationale ========
The advantages of using it are: * Be standard, ie: ** Our components will be able to be re-used by injectors other than ours (Guice for example) ** Since IDEs will support JSR330 they'll be able to offer features for our code (auto complete, graph, etc), for ex http://blogs.jetbrains.com/idea/tag/dependency-injection/
Proposed Changes ===============
Note: JSR330 doesn't specify how components should be bound, hence the need to keep xwiki-specific metadata for the bindings.
* @Component and @ComponentRole stay unchanged
Except that the package changes, right?
Nope, we keep our annotations for the bindings part since it's not part of the JSR330 spec.
* Deprecate @Requirement, replaced by @Inject * Use @Named or application-specific annotations (based on @Qualifier) instead of hints specified in the @Requirement annotation * Add new @Role(Class) to specify a dependency role in the case of collections (since generics are not available using reflection in Java)
@Role will kind of break the "be standard, so supported by other injectors" motivation. Are you sure there's no way for doing this? Maybe we should have commented during the standardization process.
Not really, binding is out of scope for JSR330. Here's what they say:
" This package provides dependency injection annotations that enable portable classes, but it leaves external dependency configuration up to the injector implementation. Programmers annotate constructors, methods, and fields to advertise their injectability (constructor injection is demonstrated in the examples above). A dependency injector identifies a class's dependencies by inspecting these annotations, and injects the dependencies at run time. Moreover, the injector can verify that all dependencies have been satisfied atbuild time. A service locator, by contrast, cannot detect unsatisfied dependencies until run time.
Injector implementations can take many forms. An injector could configure itself using XML, annotations, a DSL (domain-specific language), or even plain Java code. An injector could rely on reflection or code generation. An injector that uses compile-time code generation may not even have its own run time representation. Other injectors may not be able to generate code at all, neither at compile nor run time. A "container", for some definition, can be an injector, but this package specification aims to minimize restrictions on injector implementations. "
* Deprecate @InstantiationStrategy, replaced by @Singleton. We don't need to introduce any other scope annotations for now. * Note that the default scope in the JSR330 spec is "per lookup". Since our default is singleton, we'll need to add @Singleton annotations everywhere we used to not have anything.
This (@Singleton everywhere) is the biggest inconvenience, but we'll manage.
Yep it'll be a pain.
We also need to update the component tutorial.
Yes, and the Module doc too.
Example before:
@Component("html") public class HTMLMacro extends AbstractMacro<HTMLMacroParameters> { ... @Requirement private HTMLCleaner htmlCleaner; ... @Requirement("xhtmlmacro/1.0") private PrintRendererFactory xhtmlRendererFactory; ...
@Requirement(role = Transformation.class) private List<Transformation> transformations = new ArrayList<Transformation>();
Same example after the change:
@Component("html") public class HTMLMacro extends AbstractMacro<HTMLMacroParameters> { ... @Inject private HTMLCleaner htmlCleaner; ... @Inject @Named("xhtmlmacro/1.0") private PrintRendererFactory xhtmlRendererFactory; ...
@Inject @Role(Transformation.class) private List<Transformation> transformations = new ArrayList<Transformation>();
Right?
yes (same for Maps).
For the record, note that in Guice the binding is done like this: bind(new TypeLiteral<Map<GeneticOperator, Double>>() {}).to(...); See also http://code.google.com/p/google-guice/source/browse/trunk/src/com/google/inj...
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO