I am developing a component that declares a dependency on two services of the same
type in different roles. I have created a block.xml that constructs two components of
the same type with different contexts. Merlin is creating the appropriate appliances
(i.e. an appliance for service in role A and one for role B) but when my component
does a lookup of the service by key (role), the exact same service role is supplied.
This is the dependecy declaration...
/**
* @avalon.meta.dependency type="c.a.r.c.io.InputSource"
* @avalon.meta.dependency type="c.a.r.c.io.OutputSource" key="worklist"
* @avalon.meta.dependency type="c.a.r.c.io.OutputSource" key="completed"
* @avalon.meta.dependency type="c.a.r.c.io.RecordFormat"
* @avalon.meta.dependency type="c.a.r.s.VerificationService"
* @avalon.meta.dependency type="c.a.r.sr.LegacyHandler"
*
* @param serviceManager
* @throws ServiceException
*/
public void service(final ServiceManager serviceManager) throws ServiceException {
getLogger().debug("DefaultSolarrProcess.service()");
m_inputSource = (InputSource) serviceManager.lookup(InputSource.ROLE);
m_workListOutputSource = (OutputSource) serviceManager.lookup("worklist");
m_completedOutputSource = (OutputSource) serviceManager.lookup("completed");
m_recordFormat = (RecordFormat) serviceManager.lookup(RecordFormat.ROLE);
m_verificationService = (VerificationService)
serviceManager.lookup(VerificationService.ROLE);
m_legacyHandler = (LegacyHandler) serviceManager.lookup(LegacyHandler.ROLE);
}
...which yeilds the xinfo...
<type>
<info>
<name>DefaultSolarrProcess</name>
<version>1.0.0</version>
<lifestyle>transient</lifestyle>
</info>
<dependencies>
<dependency type="c.a.r.c.io.InputSource:1.0.0"/>
<dependency key="worklist" type="c.a.r.c.io.OutputSource:1.0.0"/>
<dependency key="completed" type="c.a.r.c.io.OutputSource:1.0.0"/>
<dependency type="c.a.r.c.io.RecordFormat:1.0.0"/>
<dependency type="c.a.r.s.VerificationService:1.0.0"/>
<dependency type="c.a.r.s.LegacyHandler:1.0.0"/>
</dependencies>
</type>
And my block.xml is...
<implementation>
<classloader>
<classpath>
<repository>
<resource id="roam-common:file-io" version="1.0"/>
<resource id="roam-solarr:solarr" version="1.0"/>
</repository>
</classpath>
</classloader>
<component name="solarr-process" class="c.a.r.s.impl.DefaultSolarrProcess"/>
<component name="input-source" class="c.a.r.c.io.impl.DebugInputSource">
<component name="completed" class="c.a.r.c.io.impl.DebugOutputSource"/>
<component name="worklist" class="c.a.r.c.io.impl.DebugOutputSource"/>
<component name="verification-service"
class="c.a.r.sr.impl.DebugVerificationService"/>
<component name="legacy-handler" class="c.a.r.s.impl.DebugLegacyHandler"/>
</implementation>
...so that each "solarr-process" dependency is declared. However, when doing a lookup
on "completed" and "worklist" the exact same service is provided (I know this because
when I log method calls to the "completed" service, the output is generated by
"worklist" service). The following code....
getLogger().info("DefaultSolarrProcess.execute()");
m_completedOutputSource.insertRecord(toInsert); //log to file
if (request.isLastWtnOnSubAccount()) {
getLogger().info(" *** is last wtn on sub account ***");
toInsert = m_recordFormat.toRecord(worklistFields(subAccountInfo, request));
m_workListOutputSource.insertRecord(toInsert); //log to file
}
...produced log messages (the second line written by
m_completedOutputSource.insertRecord() )....
[INFO ] (solarr-process): DefaultSolarrProcess.execute()
[INFO ] (worklist): 0110302468001|999888777|This is a debug response!|
[INFO ] (solarr-process): *** is last wtn on sub account ***
[INFO ] (worklist): 2221|3017793337|3017793337||Disc|Last active Wtn|
I suspect that I need to provide a Selector that will choose the appropriate service
role. If I am correct in this assessment, is it not possible for Merlin to provide a
DefaultRoleNameSelector that maps the component name (which exists in the
appliance://worklist, for example) to the lookup key used by the dependent
(serviceManager.lookup("worklist"), for example)? This will allow developers to be
explicit about the assembly (as Phoenix provides) without the need to declare and
implement the Selector and without minimizing the dynamic assembly capabilities
inherent in Merlin. Thoughts?