...
The Component
annotation is used to define the type of component, and its parameter bindings. When using Component
, the template
must not define the type, and any parameter bindings are merged in:
Code Block |
---|
controls | true |
---|
linenumbers | true |
---|
|
<a t:id="home" class="nav">Back to home</a>
|
Code Block |
---|
controls | true |
---|
linenumbers | true |
---|
|
@Component(parameters={ "page=index" })
private PageLink home;
|
...
By contrast, InjectComponent
expects the component to be already defined, and doesn't allow any configuration of it:
Code Block |
---|
controls | true |
---|
linenumbers | true |
---|
|
<t:form t:id="login"> .... </t:form>
|
Code Block |
---|
controls | true |
---|
linenumbers | true |
---|
|
@InjectComponent
private Form login;
|
...
The InjectPage
annotation is used to inject some page in the application into a field of some other page. You often see it used from event handler methods:
Code Block |
---|
controls | true |
---|
linenumbers | true |
---|
|
@InjectPage
private ConfirmRegistration confirmRegistration;
Object onSuccessFromRegistrationForm()
{
confirmRegistration.setStatus("Registration accepted");
confirmRegistration.setValidationCode(userRegistrationData.getValidationCode());
return confirmRegistration;
}
|
...
It's not uncommon to have two or more services that implement the exact same interface. When you inject, you might start by just identifying the
type of service to inject:
Code Block |
---|
controls | true |
---|
linenumbers | true |
---|
|
@Inject
private ComponentEventResultProcessor processor;
|
...
We need more information than just the service interface type in order to identify which of the three services to inject. One possibility is to inject with the correct service id:
Code Block |
---|
controls | true |
---|
linenumbers | true |
---|
|
@InjectService("ComponentEventResultProcessor")
private ComponentEventResultProcessor processor;
|
...
Instead, we should use marker annotations. If we look at TapestryModule
, where the ComponentEventResultProcessor service is defined, we'll see it identifies the necessary markers:
Code Block |
---|
controls | true |
---|
linenumbers | true |
---|
|
@Marker(
{ Primary.class, Traditional.class })
public ComponentEventResultProcessor buildComponentEventResultProcessor(
Map<Class, ComponentEventResultProcessor> configuration)
{
return constructComponentEventResultProcessor(configuration);
}
|
When a service has marker annotations, the annotations present at the point of injection (the field, method parameter, or constructor parameter) are used to select a matching service. The list of services that match by type is then filtered to only include services that have all of the marker annotations present at the point of injection.
Code Block |
---|
controls | true |
---|
linenumbers | true |
---|
|
@Inject
@Traditional @Primary
private ComponentEventResultProcessor processor;
|
...