Skip to content

.NET: Add ReferenceTrimmer and remove unused references#4487

Open
dfederm wants to merge 1 commit intomicrosoft:mainfrom
dfederm:reference-trimmer
Open

.NET: Add ReferenceTrimmer and remove unused references#4487
dfederm wants to merge 1 commit intomicrosoft:mainfrom
dfederm:reference-trimmer

Conversation

@dfederm
Copy link
Member

@dfederm dfederm commented Mar 5, 2026

Add ReferenceTrimmer to enable detection of unnecessary project, package, and assembly references during build. Remove all unused references identified by ReferenceTrimmer.

Note: Because both ProjectReferences and PackageReferences are transitive, sometimes removing an unused dependency will cause build errors due to missing a dependency that was previously pull in transitively. In these cases, the reference is explicitly added. So despite this change having many added references, it's actually reducing references as those added references were previously underdefined but existing dependencies (due to transitivity).

Disclosure: I own ReferenceTrimmer, but I do think it will be helpful to this repo, as evidenced by the many unused references it was able to identify. Adding it to your repo will help keep the references clean.

Copilot AI review requested due to automatic review settings March 5, 2026 00:59
@markwallace-microsoft markwallace-microsoft added .NET workflows Related to Workflows in agent-framework labels Mar 5, 2026
@github-actions github-actions bot changed the title Add ReferenceTrimmer and remove unused references .NET: Add ReferenceTrimmer and remove unused references Mar 5, 2026
Copy link
Contributor

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

Adds ReferenceTrimmer to the .NET build so unnecessary project/package/assembly references can be detected and removed, and then applies the tool’s findings across tests, samples, and a few libraries to reduce/normalize dependency declarations.

Changes:

  • Introduce ReferenceTrimmer as a repo-wide dependency and adjust analyzer references to be applied globally.
  • Remove unused ProjectReference / PackageReference items and add explicit references where transitive dependencies were previously masking missing direct dependencies.
  • Normalize test dependencies by removing Moq from dotnet/tests/Directory.Build.props and adding it only to the test projects that actually use it.

Reviewed changes

Copilot reviewed 51 out of 51 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
dotnet/Directory.Packages.props Adds global analyzer references and ReferenceTrimmer to apply across all projects.
dotnet/tests/Directory.Build.props Stops referencing Moq for all tests; keeps only common test infra packages.
dotnet/tests/OpenAIResponse.IntegrationTests/OpenAIResponse.IntegrationTests.csproj Removes an unused OpenAI project reference; relies on MEAI OpenAI package instead.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Microsoft.Agents.AI.Workflows.UnitTests.csproj Marks analyzer project reference as used; adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests.csproj Adds Moq; removes unused FluentAssertions.
dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests.csproj Removes unused FluentAssertions.
dotnet/tests/Microsoft.Agents.AI.UnitTests/Microsoft.Agents.AI.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.Purview.UnitTests/Microsoft.Agents.AI.Purview.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/Microsoft.Agents.AI.OpenAI.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.Mem0.UnitTests/Microsoft.Agents.AI.Mem0.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.Mem0.IntegrationTests/Microsoft.Agents.AI.Mem0.IntegrationTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.Hosting.UnitTests/Microsoft.Agents.AI.Hosting.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests/Microsoft.Agents.AI.Hosting.OpenAI.UnitTests.csproj Removes now-unnecessary conditional package references.
dotnet/tests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests.csproj Removes unused project reference; adds explicit configuration packages.
dotnet/tests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.UnitTests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.UnitTests.csproj Replaces unused FluentAssertions reference with Moq.
dotnet/tests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.IntegrationTests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.IntegrationTests.csproj Adds framework-compatibility conditions for some package references; swaps in Workflows project reference.
dotnet/tests/Microsoft.Agents.AI.Hosting.A2A.UnitTests/Microsoft.Agents.AI.Hosting.A2A.UnitTests.csproj Adds Moq; removes no-longer-needed conditional packages.
dotnet/tests/Microsoft.Agents.AI.DevUI.UnitTests/Microsoft.Agents.AI.DevUI.UnitTests.csproj Replaces unused OpenAI package reference with Moq.
dotnet/tests/Microsoft.Agents.AI.Declarative.UnitTests/Microsoft.Agents.AI.Declarative.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.CosmosNoSql.UnitTests/Microsoft.Agents.AI.CosmosNoSql.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.AzureAI.UnitTests/Microsoft.Agents.AI.AzureAI.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.AzureAI.Persistent.UnitTests/Microsoft.Agents.AI.AzureAI.Persistent.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.Anthropic.UnitTests/Microsoft.Agents.AI.Anthropic.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.Abstractions.UnitTests/Microsoft.Agents.AI.Abstractions.UnitTests.csproj Adds Moq explicitly.
dotnet/tests/Microsoft.Agents.AI.AGUI.UnitTests/Microsoft.Agents.AI.AGUI.UnitTests.csproj Replaces unused FluentAssertions reference with Moq.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Microsoft.Agents.AI.Workflows.Declarative.csproj Makes System.CodeDom conditional to avoid redundant net472 package reference.
dotnet/src/Microsoft.Agents.AI.Mem0/Microsoft.Agents.AI.Mem0.csproj Adds explicit logging abstractions dependency.
dotnet/src/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.csproj Replaces unused hosting project reference with required package/project references.
dotnet/src/Microsoft.Agents.AI.Abstractions/Microsoft.Agents.AI.Abstractions.csproj Removes unused logging abstractions package reference.
dotnet/src/Microsoft.Agents.AI.AGUI/Microsoft.Agents.AI.AGUI.csproj Removes unused abstractions project reference.
dotnet/samples/05-end-to-end/M365Agent/M365Agent.csproj Switches from OpenAI project reference to core AI project and MEAI OpenAI package usage.
dotnet/samples/05-end-to-end/HostedAgents/AgentsInWorkflows/AgentsInWorkflows.csproj Removes analyzer reference removal block (no longer needed with global refs).
dotnet/samples/05-end-to-end/HostedAgents/AgentWithTools/AgentWithTools.csproj Removes analyzer reference removal block.
dotnet/samples/05-end-to-end/HostedAgents/AgentWithTextSearchRag/AgentWithTextSearchRag.csproj Removes analyzer reference removal block.
dotnet/samples/05-end-to-end/HostedAgents/AgentWithLocalTools/AgentWithLocalTools.csproj Removes analyzer reference removal block.
dotnet/samples/05-end-to-end/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj Removes analyzer reference removal block.
dotnet/samples/05-end-to-end/HostedAgents/AgentThreadAndHITL/AgentThreadAndHITL.csproj Removes analyzer reference removal block.
dotnet/samples/05-end-to-end/AspNetAgentAuthorization/Service/Service.csproj Switches from OpenAI project reference to core AI project and MEAI OpenAI package usage.
dotnet/samples/05-end-to-end/AgentWithPurview/AgentWithPurview.csproj Removes OpenAI project reference; adds MEAI OpenAI package reference.
dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.Web/AgentWebChat.Web.csproj Removes hosting OpenAI project reference; adds MEAI OpenAI package reference.
dotnet/samples/05-end-to-end/AGUIClientServer/AGUIServer/AGUIServer.csproj Adjusts AGUI-related project references and adds net10 compatibility conditions.
dotnet/samples/05-end-to-end/AGUIClientServer/AGUIDojoServer/AGUIDojoServer.csproj Removes unused project references; adds MEAI OpenAI package reference.
dotnet/samples/04-hosting/A2A/A2AAgent_PollingForTaskCompletion/A2AAgent_PollingForTaskCompletion.csproj Removes unused references (OpenAI project + async interfaces package).
dotnet/samples/03-workflows/_StartHere/05_SubWorkflows/05_SubWorkflows.csproj Adds net10 compatibility condition to avoid redundant direct reference.
dotnet/samples/02-agents/DeclarativeAgents/ChatClient/DeclarativeChatClientAgents.csproj Makes OpenAI project reference conditional; relies on packages for net10 path.
dotnet/samples/02-agents/Agents/Agent_Step17_AdditionalAIContext/Agent_Step17_AdditionalAIContext.csproj Adds net10 compatibility conditions around object model refs.
dotnet/samples/02-agents/Agents/Agent_Step16_Declarative/Agent_Step16_Declarative.csproj Makes OpenAI project reference conditional for net10.
dotnet/samples/02-agents/Agents/Agent_Step11_Middleware/Agent_Step11_Middleware.csproj Replaces OpenAI project reference with MEAI OpenAI package reference.
dotnet/samples/02-agents/AgentWithOpenAI/Agent_OpenAI_Step02_Reasoning/Agent_OpenAI_Step02_Reasoning.csproj Replaces OpenAI project reference with core AI + MEAI OpenAI package references.
dotnet/samples/02-agents/AgentProviders/Agent_With_CustomImplementation/Agent_With_CustomImplementation.csproj Replaces direct AI project reference with explicit AI abstractions + MEAI package dependency.
dotnet/samples/02-agents/AgentOpenTelemetry/AgentOpenTelemetry.csproj Makes OpenAI project reference conditional for net10.
Comments suppressed due to low confidence (1)

dotnet/samples/05-end-to-end/AgentWebChat/AgentWebChat.Web/AgentWebChat.Web.csproj:19

  • This project’s code uses OpenAI SDK types directly (e.g., OpenAIClientOptions, ChatClient, ResponsesClient under AgentWebChat.Web/*) but the project file only references Microsoft.Extensions.AI.OpenAI. Consider adding an explicit PackageReference to OpenAI so the build doesn’t depend on Microsoft.Extensions.AI.OpenAI continuing to bring the OpenAI SDK transitively.
  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Hosting.A2A\Microsoft.Agents.AI.Hosting.A2A.csproj" />
    <ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Hosting\Microsoft.Agents.AI.Hosting.csproj" />
    <ProjectReference Include="..\AgentWebChat.ServiceDefaults\AgentWebChat.ServiceDefaults.csproj" />
    <ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
  </ItemGroup>

Comment on lines +156 to +163
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.100" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15" />
<GlobalPackageReference Include="xunit.analyzers" Version="1.23.0" />
<GlobalPackageReference Include="Moq.Analyzers" Version="0.3.1" />
<GlobalPackageReference Include="Roslynator.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="Roslynator.Formatting.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="ReferenceTrimmer" Version="3.4.5" />
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

These analyzer/tool packages were previously referenced with PrivateAssets=all and restricted IncludeAssets so they don’t flow to downstream consumers. With GlobalPackageReference and no metadata, they may become transitive dependencies and/or bring runtime/build assets into projects unexpectedly. Consider adding PrivateAssets="all" and the equivalent IncludeAssets (e.g., analyzers/build/buildTransitive only) for these global references, and keep versions in PackageVersion items if you want consistent central management.

Suggested change
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.100" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15" />
<GlobalPackageReference Include="xunit.analyzers" Version="1.23.0" />
<GlobalPackageReference Include="Moq.Analyzers" Version="0.3.1" />
<GlobalPackageReference Include="Roslynator.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="Roslynator.Formatting.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="ReferenceTrimmer" Version="3.4.5" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.100" PrivateAssets="all" IncludeAssets="analyzers;build;buildTransitive" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15" PrivateAssets="all" IncludeAssets="analyzers;build;buildTransitive" />
<GlobalPackageReference Include="xunit.analyzers" Version="1.23.0" PrivateAssets="all" IncludeAssets="analyzers;build;buildTransitive" />
<GlobalPackageReference Include="Moq.Analyzers" Version="0.3.1" PrivateAssets="all" IncludeAssets="analyzers;build;buildTransitive" />
<GlobalPackageReference Include="Roslynator.Analyzers" Version="4.14.1" PrivateAssets="all" IncludeAssets="analyzers;build;buildTransitive" />
<GlobalPackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.14.1" PrivateAssets="all" IncludeAssets="analyzers;build;buildTransitive" />
<GlobalPackageReference Include="Roslynator.Formatting.Analyzers" Version="4.14.1" PrivateAssets="all" IncludeAssets="analyzers;build;buildTransitive" />
<GlobalPackageReference Include="ReferenceTrimmer" Version="3.4.5" PrivateAssets="all" IncludeAssets="analyzers;build;buildTransitive" />

Copilot uses AI. Check for mistakes.
Comment on lines +156 to +163
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.100" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15" />
<GlobalPackageReference Include="xunit.analyzers" Version="1.23.0" />
<GlobalPackageReference Include="Moq.Analyzers" Version="0.3.1" />
<GlobalPackageReference Include="Roslynator.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="Roslynator.Formatting.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="ReferenceTrimmer" Version="3.4.5" />
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

ReferenceTrimmer (and the remaining analyzer global references in this ItemGroup) should likely be marked as build-time only (e.g., PrivateAssets=all plus appropriate IncludeAssets) so it doesn’t become a transitive NuGet dependency of produced packages. Right now the GlobalPackageReference entries have no such metadata, which can change dependency graphs compared to the previous PackageReference approach.

Suggested change
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.100" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15" />
<GlobalPackageReference Include="xunit.analyzers" Version="1.23.0" />
<GlobalPackageReference Include="Moq.Analyzers" Version="0.3.1" />
<GlobalPackageReference Include="Roslynator.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="Roslynator.Formatting.Analyzers" Version="4.14.1" />
<GlobalPackageReference Include="ReferenceTrimmer" Version="3.4.5" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.100" PrivateAssets="all" IncludeAssets="analyzers" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15" PrivateAssets="all" IncludeAssets="analyzers" />
<GlobalPackageReference Include="xunit.analyzers" Version="1.23.0" PrivateAssets="all" IncludeAssets="analyzers" />
<GlobalPackageReference Include="Moq.Analyzers" Version="0.3.1" PrivateAssets="all" IncludeAssets="analyzers" />
<GlobalPackageReference Include="Roslynator.Analyzers" Version="4.14.1" PrivateAssets="all" IncludeAssets="analyzers" />
<GlobalPackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.14.1" PrivateAssets="all" IncludeAssets="analyzers" />
<GlobalPackageReference Include="Roslynator.Formatting.Analyzers" Version="4.14.1" PrivateAssets="all" IncludeAssets="analyzers" />
<GlobalPackageReference Include="ReferenceTrimmer" Version="3.4.5" PrivateAssets="all" IncludeAssets="analyzers" />

Copilot uses AI. Check for mistakes.
Comment on lines 9 to 13
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\AgentConformance.IntegrationTests\AgentConformance.IntegrationTests.csproj" />
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

This project uses the OpenAI SDK types (e.g., OpenAIClient / OpenAI.Responses) in OpenAIResponseFixture.cs but only references Microsoft.Extensions.AI.OpenAI. To avoid relying on transitive package dependencies, add a direct PackageReference to the OpenAI package (or ensure it’s referenced in a way that won’t change if Microsoft.Extensions.AI.OpenAI updates its dependency graph).

Copilot uses AI. Check for mistakes.

<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" Condition="!$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net10.0'))" />
Copy link
Contributor

@westey-m westey-m Mar 5, 2026

Choose a reason for hiding this comment

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

Since this project is only targeting net 10.0, this condition will never be true, and therefore this reference can be removed in its entirety.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same for a few other sample projects below as well.

<ItemGroup>
<PackageReference Include="coverlet.collector" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Moq" />
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we keep this here, to avoid adding it to many test projects individually? While it may not be used in each test project, it's used in most of them, and having the extra dependency is OK for test projects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET workflows Related to Workflows in agent-framework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants