Disambiguation
Overview
You may have a component that has a dependency on something that the
container could ordinarily satisfy more than one. By default,
when PicoContainer is presented with such a situation, it will throw an
exception suggesting the dependency resolution is ambiguous.
Disambiguation using parameter names
With PicoContainer 2.0 we are able to leverage the parameter names of
constructors and methods in order to remove the ambiguity on
dependancies.
public class Store {
public Store(StockManager workingDayStockManager, StockManager afterHoursStockManager) {
// etc
}
}
If Store is added to the container appropriately, then its parameter
names
'workingHoursStockManager'
and 'afterHoursStockManager
' can be used in conjunction with similarly named components inject the
right dependency in the right way:
pico.as(Characteristics.USE_NAMES).addComponent(Store.class);
Access to parameter names was dropped from JDK 6.0 and it is uncertain
whether it will be added as a feature in another release, so
PicoContainer relies on another open source library called
Paranamer,
without requiring a dependency on its Jar. In other words,
PicoContainer has the same classes from Paranamer in its jar.
See
CommandLineArgumentsPicoContainer,
PropertiesPicoContainer
and
SystemPropertiesPicoContainer
for implementations of PicoContainer that set up components for
subsequent parameter name binding.
Page
component-configuration
also shows parameter names being used for binding as does
injection.
Usage of parameter names is available for all types of
Dependency-Injection where parameter names are present.
Disambiguation using Binding Annotations
This works the same as Guice. Namely you make an
annotation that extends our 'Bind' annotation and mark it in your constructor or method's signature like so.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Bind
public static @interface WorkingDayStockManager {
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Bind
public static @interface AfterHoursStockManager {
}
public class Store {
public Store(@WorkingDayStockManager StockManager workingDayStockManager,
@AfterHoursStockManager StockManager afterHoursStockManager) {
// etc
}
}
Making PicoContainer leverage binding annotations if present is
automatic.
Binding
annotations can be specified for constructor parameters (as shown above),
method injection parameters as well as field injection.