Skip to content

Order assembly loading deterministically - #3

Merged
sakanni merged 1 commit into
developfrom
fix/deterministic-assembly-load-order
Aug 20, 2026
Merged

Order assembly loading deterministically#3
sakanni merged 1 commit into
developfrom
fix/deterministic-assembly-load-order

Conversation

@sakanni

@sakanni sakanni commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

This does not fix CI_Toolkit#161. It makes the collision deterministic, not correct. Read the title as "the answer no longer depends on the filesystem", not as "the right assembly now answers".

ProbeDeclaringType takes its verdict from the first loaded assembly that yields the declaring type. Directory.GetFiles documents no ordering, so on any closure where two assemblies define the same type name the classification depended on the filesystem. That is #161's mechanism, and it is not a single case: 42 type names across the fleet are defined by more than one assembly, 9 of them across repository boundaries.

After this change Revit_Core_Engine_2022 wins that contest consistently, because C sorts before M. That is the right claimant when the subject is Revit_Toolkit and the wrong one when the subject is the other repo, and it is now wrong reproducibly rather than intermittently. The 811 dataset entries that a Revit_ModelQA_Tool run would attribute to the wrong repo are untouched by this. #161 stays open and still needs either declaring-assembly attribution or its option 3, moving the colliding type into its own namespace at source.

What this does buy is that the remaining problem no longer moves under measurement, which is a precondition for the differential work rather than a fix in itself.

Measured on windows-2025-vs2026 across four cold-rebuild runs on separate runners, NTFS returned exactly StringComparer.OrdinalIgnoreCase order every time, 132 and 111 entries. So this is a no-op there and the change is defensive. It converts an observation about one filesystem into a property of the code.

The comparer is not interchangeable, which is why a test names it. On the real 132-assembly closure, Ordinal, OrdinalIgnoreCase and a lowercase-based sort each produce a different order, and only OrdinalIgnoreCase reproduces what NTFS returned. It uppercases before comparing, so _ (0x5F) lands after letters and RevitAPIUI precedes Revit_Adapter; a lowercase sort reverses that pair and would change which assembly answers for a contested type.

Eight tests, four mutations, each caught by the intended one: no sort, lowercase sort, plain Ordinal, and sorting the whole path instead of the file name.

@sakanni
sakanni merged commit 2061d7c into develop Aug 20, 2026
1 check passed
@sakanni
sakanni deleted the fix/deterministic-assembly-load-order branch August 20, 2026 01:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant