Skip to content

Conversation

twsouthwick
Copy link
Member

@twsouthwick twsouthwick commented Jul 16, 2025

Description

This enables scenarios to use the library on .NET Framework. This is mostly done by using C# 14 new extension syntax so very little code changes were made but rather the APIs that didn't exist are added into FrameworkExtensions classes to light them up on .NET Core builds.

NOTE: This updates the abstractions and main ServiceDiscovery library, but does not enable the DNS nor YARP. YARP isn't supported on framework, so that isn't necessary. The DNS has a larger change due to more APIs it's using that don't exist, so once this PR gets in I can push that up if this pattern works.

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

This enables scenarios to use the library on .NET Framework. This is mostly done by using C# 14 new extension syntax so very little code changes were made but rather the APIs that didn't exist are added into FrameworkExtensions classes to light them up on .NET Core builds.
@twsouthwick twsouthwick force-pushed the servicediscovery-fx branch from aa30c55 to 17f3a62 Compare July 16, 2025 23:17
@twsouthwick twsouthwick marked this pull request as ready for review July 16, 2025 23:17
@Copilot Copilot AI review requested due to automatic review settings July 16, 2025 23:17
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enables the ServiceDiscovery library and its tests to build and run on .NET Framework by multi-targeting the projects and providing polyfills for newer APIs via C# 14 extension syntax.

  • Multi-target key projects and tests against net462/net472 alongside existing frameworks.
  • Added a shared FxPolyfills folder with extension methods to surface missing .NET Core APIs on .NET Framework.
  • Updated test and service discovery projects to conditionally include additional references and imports.

Reviewed Changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/Shared/TemplatesTesting/Aspire.Shared.TemplatesTesting.targets Added IncludeTestUtilities property and removed direct test utilities reference
tests/Microsoft.Extensions.ServiceDiscovery.Tests/…Tests.cs Suppressed a type conflict warning around the fake resolver factory
tests/**/*.csproj Switched to multi-targeting net472 on Windows and added framework-specific package imports
tests/Aspire.TestUtilities/Aspire.TestUtilities.csproj Multi-target net472 and import polyfills targets for framework support
src/Shared/FxPolyfills/*.cs Introduced extension polyfills for various System and threading APIs on .NET Framework
src/Shared/FxPolyfills/FxPolyfills.targets Configured inclusion/exclusion of polyfill sources based on targeting
src/Microsoft.Extensions.ServiceDiscovery*.csproj Multi-target net462, conditional AOT flag, reference Bcl packages, and import polyfills
src/Microsoft.Extensions.ServiceDiscovery/ServiceDiscoveryHttpClientBuilderExtensions.cs Wrapped gRPC-disable filter in #if NET for proper cross-target behavior
eng/Versions.props & Directory.Packages.props Added and updated version properties for newly referenced packages
Comments suppressed due to low confidence (3)

tests/Shared/TemplatesTesting/Aspire.Shared.TemplatesTesting.targets:18

  • The ProjectReference to Aspire.TestUtilities was removed, which may break resolution of the RequiresDocker attribute and other test utilities. Please re-add or replace this reference so that the shared test utilities are included in the build.
  </ItemGroup>

src/Shared/FxPolyfills/Task.cs:20

  • Add unit tests for FxPolyfillTask.ConfigureAwait covering each ConfigureAwaitOptions path to ensure the polyfill behaves identically to its .NET Core counterpart.
        public async Task ConfigureAwait(ConfigureAwaitOptions options)

src/Shared/FxPolyfills/Task.TimeProvider.cs:12

  • Consider adding tests for FxPolyfillTask.WaitAsync to validate timeout and cancellation behavior on .NET Framework scenarios.
        public Task WaitAsync(CancellationToken token)

@CZEMacLeod
Copy link

These polyfills are excellent. I wish there was an official MS polyfill for net4x, to prevent multiple copies of classes/code in each dll.


<!-- Include all Framework Extension files from the shared location, excluding test-specific ones -->
<ItemGroup Condition="$(IsTargetingNetFramework)">
<Reference Include="System.Net.Http" />
Copy link
Member

Choose a reason for hiding this comment

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

NIT: should this go directly into projects that need it as opposed to globally? It helps with readability when references are all in the same project file.

Copy link
Member Author

Choose a reason for hiding this comment

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

I put it here because these are usings that are already automatically added to the projects for .net 8/9, so it continues to be transparent to the consuming library.


<PropertyGroup>
<TargetFramework>$(DefaultTargetFramework)</TargetFramework>
<TargetFrameworks>$(DefaultTargetFramework);net472</TargetFrameworks>
Copy link
Member

Choose a reason for hiding this comment

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

Why some are net462 and some net472?

Copy link
Member Author

Choose a reason for hiding this comment

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

net462 is the minimum supported framework for the runtime libraries so makes sense to continue supporting that. However, xunit and other testing utilities have a minimum of net472

<PropertyGroup>
<TargetFramework>$(DefaultTargetFramework)</TargetFramework>
<TargetFrameworks>$(DefaultTargetFramework)</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('Windows'))">$(TargetFrameworks);net472</TargetFrameworks>
Copy link
Member

Choose a reason for hiding this comment

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

Why do we condition this here but not in the other test project?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because this is an exe and won't run on non-windows while the other is just a build time time. If there's a way to remove it from test runs on non-windows, we can still build it for net472, I've just always done it this way.

@joperezr
Copy link
Member

joperezr commented Aug 1, 2025

Most of the comments are nits, but this looks really good otherwise, thanks @twsouthwick!

I don't love the name of FxPollyfills, but I also don't have a good alternative 😄

Copy link
Member

@joperezr joperezr left a comment

Choose a reason for hiding this comment

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

Kind of a tangent, but any reason why we are not also cross compiling The Dns and Yarp ServiceDiscovery packages?

@twsouthwick
Copy link
Member Author

Kind of a tangent, but any reason why we are not also cross compiling The Dns and Yarp ServiceDiscovery packages?

I mentioned in the original comment, but DNS requires quite a bit more for the polyfills so my plan was to make sure the pattern was OK before including that. YARP only supports .NET 6+, so it can't be supported there

@davidfowl
Copy link
Member

why net462 and not just 48?

@joperezr
Copy link
Member

why net462 and not just 48?

I would suggest targeting the lowest version of netfx still in support, which is net462 for now.

@twsouthwick
Copy link
Member Author

I realized we could just target netstandard2.0 which can help with migration efforts even more. I've pushed a change that removes explicitly targeting net462 with netstandard2.0.

I'm not sure what the current recommended practice for multi-targeting is, so I can add the net462 if there is a reason to be explicit about it.

@twsouthwick twsouthwick changed the title Build ServiceDiscovery library and tests against .NET Framework Build ServiceDiscovery library and tests against .NET Standard Aug 25, 2025
@twsouthwick twsouthwick changed the title Build ServiceDiscovery library and tests against .NET Standard Build ServiceDiscovery library and tests against netstandard2.0 Aug 25, 2025
@joperezr
Copy link
Member

I realized we could just target netstandard2.0 which can help with migration efforts even more. I've pushed a change that removes explicitly targeting net462 with netstandard2.0.

I'm not sure what the current recommended practice for multi-targeting is, so I can add the net462 if there is a reason to be explicit about it.

I think it would be good to bring it back. We have public docs somewhere that w recommend library devs to consider also targeting netfx explicitly when targeting ns2.0 mainly to help avoid binding redirect issues. I somehow can't find those docs now, but for that reason it might be good to add it back.

Copy link
Member

@joperezr joperezr left a comment

Choose a reason for hiding this comment

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

Other than adding back the netfx target, this LGTM. Thanks @twsouthwick and sorry for the wait!

@davidfowl davidfowl merged commit cf73505 into dotnet:main Aug 25, 2025
292 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the 9.5 milestone Aug 25, 2025
@twsouthwick twsouthwick deleted the servicediscovery-fx branch August 26, 2025 16:21
twsouthwick added a commit to twsouthwick/aspire that referenced this pull request Aug 26, 2025
An add on from  dotnet#10470 that added support for netstandard2.0, this adds
an explicit net472 target which is part of the recommendation for
multi-targetd libraries.
twsouthwick added a commit to twsouthwick/aspire that referenced this pull request Aug 26, 2025
An add on from  dotnet#10470 that added support for netstandard2.0, this adds
an explicit net472 target which is part of the recommendation for
multi-targetd libraries.
twsouthwick added a commit to twsouthwick/aspire that referenced this pull request Aug 26, 2025
An add on from  dotnet#10470 that added support for netstandard2.0, this adds
an explicit net462 target which is part of the recommendation for
multi-targetd libraries.
twsouthwick added a commit to twsouthwick/aspire that referenced this pull request Aug 26, 2025
An add on from  dotnet#10470 that added support for netstandard2.0, this adds
an explicit net462 target which is part of the recommendation for
multi-targetd libraries.
twsouthwick added a commit to twsouthwick/aspire that referenced this pull request Aug 26, 2025
An add on from  dotnet#10470 that added support for netstandard2.0, this adds
an explicit net462 target which is part of the recommendation for
multi-targetd libraries.
twsouthwick added a commit that referenced this pull request Sep 2, 2025
An add on from  #10470 that added support for netstandard2.0, this adds
an explicit net462 target which is part of the recommendation for
multi-targeted libraries.
Copilot AI pushed a commit that referenced this pull request Sep 3, 2025
An add on from  #10470 that added support for netstandard2.0, this adds
an explicit net462 target which is part of the recommendation for
multi-targeted libraries.
@github-actions github-actions bot locked and limited conversation to collaborators Sep 26, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants