Injection
What's the difference between the Component and InjectComponent annotations?
What's the difference between the InjectPage and InjectContainer annotations?
I get an exception because I have two services with the same interface, how do I handle this?
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:
@Inject
private ComponentEventResultProcessor processor;
Which results in the error: Service interface org.apache.tapestry5.services.ComponentEventResultProcessor is matched by 3 services: AjaxComponentEventResultProcessor, ComponentEventResultProcessor, ComponentInstanceResultProcessor. Automatic dependency resolution requires that exactly one service implement the interface.
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:
@InjectService("ComponentEventResultProcessor")
private ComponentEventResultProcessor processor;
This works ... but it is clumsy. If the service id, "ComponentEventResultProcessor", ever changes, this code will break. It's not refactoring safe.
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:
@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.
@Traditional @Primary
private ComponentEventResultProcessor processor;