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?

Reply via email to