I am risking showing my ignorance about this...
Some declarations of the @Service specify a name. (See FileArchive
which specifies "file" and JarInputArchive which specifies "jar".)
Both of these classes implement ReadableArchive.
The ArchiveFactory class uses habitat.getComponent(Class,String) and
specifies ReadableArchive.class as the Class and the scheme from a URI
(e.g., "file" or "jar") as the name. The habitat finds an
implementation of that interface with the requested name.
I suspect getInhabitantByContract(Class,String) is doing something
similar to what getComponent(Class,String) does. I expect the latter
delegates to the former. But I do not know for sure.
Iterating is probably the only game in town for this. There is no
priority mechanism I'm aware of, and I suspect that's due in part to
the fact that different clients of the habitat might have different
ideas about which implementation of a given contract is the "highest
priority" one.
It's a bit ugly, but I suppose you could introduce the new interface
Prioritized with method int priority(). They your code could get the
objects which match ConfigurationUpgrade, and of those which also
implement Prioritized it could process those in priority order,
relegating the non-prioritized ones to an indeterminate order after
the prioritized objects have been processed.
This way only the upgraders that want to express a priority need to
change, rather than all the upgraders.
Just a thought...
- Tim
On Dec 17, 2010, at 9:28 AM, Bobby Bissett wrote:
>> If you don't mind changing all 15 implementers of
>> ConfigurationUpgrade, you could add a method to that interface that
>> returns a priority, and then sort the list that is returned by
>> getInhabitants before running them.
>
> Thanks. I'd rather not do that at this point since there's already
> the "inject other class first" method and I thought there was some
> system of priorities that already existed.
>
> I think the best fix for this is simply to have all upgrade code in
> the same package instead of spread around. I know that breaks the
> loose coupling we have, but as we can see in this case there really
> is no loose coupling when dealing with the config api objects (e.g.
> you can't save a cluster without saving some gms attributes).
>
> If I don't get an answer, I can do the iteration to get the one I
> need by using typeName(). I'd like to keep this change as small as
> possible and consider a more general fix in 3.2.
>
> Cheers,
> Bobby
>