Skip to content

Fix TFM ordering in Dependencies tab using NuGetFrameworkSorter#10655

Draft
Copilot wants to merge 9 commits intodevfrom
copilot/fix-tfm-sorting-issue
Draft

Fix TFM ordering in Dependencies tab using NuGetFrameworkSorter#10655
Copilot wants to merge 9 commits intodevfrom
copilot/fix-tfm-sorting-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Dec 10, 2025

Fix TFM Ordering in Dependencies Tab ✅

  • Understand the current implementation in DependencySetsViewModel
  • Modify DependencySetsViewModel to use NuGetFrameworkSorter instead of lexicographic sorting
  • Add test cases to verify net10.0 is sorted after net9.0
  • Code review completed - no issues
  • Security check completed - no vulnerabilities found
  • Address PR feedback: use case-insensitive Id sorting
  • Address PR feedback: simplify framework comparer to use NuGetFrameworkSorter directly
  • Fix test failure: update expected values to match actual ToFriendlyName() output
  • Add static Instance property to NullableFrameworkComparer for performance
  • Fix code style: move array initializer opening brace to next line
  • Use IReadOnlyList to explicitly guarantee ordering instead of relying on Dictionary
  • Fix test compilation errors for IReadOnlyList usage
  • Add missing System.Collections.Generic using statement

Changes Summary

Problem: The Dependencies tab was sorting TFMs (Target Framework Monikers) lexicographically by their friendly name strings, causing net10.0 to appear before net8.0 and net9.0.

Solution: Modified DependencySetsViewModel to:

  1. Parse TFM strings as NuGetFramework objects
  2. Sort using NuGetFrameworkSorter.Instance which properly handles framework identifier and version
  3. Maintain "All Frameworks" at the top of the list
  4. Use case-insensitive sorting for package IDs within each framework
  5. Cache NullableFrameworkComparer instance via static readonly property for better performance
  6. Use IReadOnlyList<KeyValuePair<...>> to explicitly guarantee ordering (not relying on Dictionary implementation details)

Test Coverage:

  • Added GivenAListOfDependenciesNet10WillBeOrderedAfterNet9 test to verify correct ordering of net8.0, net9.0, and net10.0
  • Added GivenAListOfDependenciesPackageIdsWillBeOrderedCaseInsensitively test to verify case-insensitive package ID sorting
  • Fixed test expectations to match actual ToFriendlyName() behavior for modern .NET TFMs (net8.0, net9.0, net10.0 remain as-is)
  • Fixed code style to follow repository conventions (opening braces on new line for array initializers)
  • Updated tests to work with ordered list using Select to access keys
  • Added missing using statement for System.Collections.Generic

Security Summary

No security vulnerabilities were introduced by these changes.

Original prompt

This section details on the original issue you should resolve

<issue_title>Dependencies tab should properly order TFMs</issue_title>
<issue_description>net10.0 is being sorted to before net8.0. It should be at the bottom, after net9.0.

Image</issue_description>

<agent_instructions>Check the screenshot. It shows that net10.0 is sorted before net8.0. This is likely because the dependency group TFMs (target framework monikers) are sorted in lex order and not by framework name first, and then version. "net" should be sorted separately than "10.0" in other words. The string can be parsed as a NuGetFramework (they maybe a convenience property on the data model to do this... I forget). If so, do the sorting on the NuGetFramework name and then version (I don't remember those property names either.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

… sorting

Co-authored-by: joelverhagen <94054+joelverhagen@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix sorting order of TFMs in dependencies tab Fix TFM ordering in Dependencies tab using NuGetFrameworkSorter Dec 10, 2025
Copilot AI requested a review from joelverhagen December 10, 2025 17:13
…mework comparer

Co-authored-by: joelverhagen <94054+joelverhagen@users.noreply.github.com>
Co-authored-by: joelverhagen <94054+joelverhagen@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Dec 10, 2025

@copilot your PR is failing with this test

##[error][xUnit.net 00:03:34.07] NuGetGallery.ViewModels.DependencySetsViewModelFacts+TheConstructor.GivenAListOfDependenciesNet10WillBeOrderedAfterNe...

Fixed the test expectations. The ToFriendlyName() method for modern .NET TFMs (net8.0, net9.0, net10.0) returns the short form as-is, not a friendly display name like ".NET 8.0". Updated the test to expect "net8.0", "net9.0", and "net10.0" instead. (70ce314)

Co-authored-by: joelverhagen <94054+joelverhagen@users.noreply.github.com>
Co-authored-by: joelverhagen <94054+joelverhagen@users.noreply.github.com>
@joelverhagen joelverhagen marked this pull request as ready for review December 10, 2025 19:15
@joelverhagen joelverhagen requested a review from a team as a code owner December 10, 2025 19:15
@joelverhagen
Copy link
Copy Markdown
Member

I validated this change locally. Good robot.

{
if (!DependencySets.ContainsKey(group.friendlyName))
{
DependencySets.Add(group.friendlyName, group.dependencies);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very confused how this works. Why does DependencySets.Keys return the keys ordered how you expect them to?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to address (at)copilot to get a response.
I missed this, I had assumed this was a collection that supported the order as we'd expect. I think this is working because of a Dictionary implementation detail -- not good.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot - can you check this comment thread please?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct that relying on Dictionary insertion order was problematic, especially for .NET Framework 4.7.2 where it's not guaranteed. Changed DependencySets from IDictionary<string, IEnumerable<DependencyViewModel>> to IReadOnlyList<KeyValuePair<string, IEnumerable<DependencyViewModel>>> to explicitly preserve the sorted order. The sorted frameworks are now stored in a List which guarantees insertion order, making the ordering contract explicit. (7a1b3c0)

Copilot AI and others added 2 commits December 11, 2025 15:58
…ing on Dictionary implementation

Co-authored-by: joelverhagen <94054+joelverhagen@users.noreply.github.com>
Co-authored-by: joelverhagen <94054+joelverhagen@users.noreply.github.com>
@joelverhagen
Copy link
Copy Markdown
Member

@copilot check these build errors

       "D:\a\_work\1\ng\NuGetGallery.sln" (default target) (1) ->
       "D:\a\_work\1\ng\tests\NuGetGallery.Facts\NuGetGallery.Facts.csproj" (default target) (19) ->
       (CoreCompile target) -> 
         D:\a\_work\1\ng\tests\NuGetGallery.Facts\ViewModels\DependencySetsViewModelFacts.cs(58,67): error CS1061: 'IReadOnlyList<KeyValuePair<string, IEnumerable<DependencySetsViewModel.DependencyViewModel>>>' does not contain a definition for 'Keys' and no accessible extension method 'Keys' accepting a first argument of type 'IReadOnlyList<KeyValuePair<string, IEnumerable<DependencySetsViewModel.DependencyViewModel>>>' could be found (are you missing a using directive or an assembly reference?) [D:\a\_work\1\ng\tests\NuGetGallery.Facts\NuGetGallery.Facts.csproj]
         D:\a\_work\1\ng\tests\NuGetGallery.Facts\ViewModels\DependencySetsViewModelFacts.cs(139,67): error CS1061: 'IReadOnlyList<KeyValuePair<string, IEnumerable<DependencySetsViewModel.DependencyViewModel>>>' does not contain a definition for 'Keys' and no accessible extension method 'Keys' accepting a first argument of type 'IReadOnlyList<KeyValuePair<string, IEnumerable<DependencySetsViewModel.DependencyViewModel>>>' could be found (are you missing a using directive or an assembly reference?) [D:\a\_work\1\ng\tests\NuGetGallery.Facts\NuGetGallery.Facts.csproj]

Co-authored-by: joelverhagen <94054+joelverhagen@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Dec 11, 2025

@copilot check these build errors

       "D:\a\_work\1\ng\NuGetGallery.sln" (default target) (1) ->

...

Fixed by adding the missing using System.Collections.Generic; statement to the test file. The IReadOnlyList<KeyValuePair<...>> type requires this namespace import. (d86e79d)

NuGetFramework framework;

if (!DependencySets.ContainsKey(targetFramework))
if (tfmString == null)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string.IsNullOrEmpty(tfmString )

@pranathibora14 pranathibora14 marked this pull request as draft March 3, 2026 21:58
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.

4 participants