Add project reference support for polyglot apphost integrations#14821
Add project reference support for polyglot apphost integrations#14821davidfowl merged 26 commits intorelease/13.2from
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 14821Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 14821" |
There was a problem hiding this comment.
Pull request overview
Adds support for using local .csproj project references (in addition to NuGet package versions) for polyglot AppHost integrations via .aspire/settings.json, enabling local integration authoring/testing without publishing to a feed.
Changes:
- Introduces
IntegrationReferenceand updates configuration parsing to treat values ending in.csprojas project references. - Updates AppHost server preparation flow to accept integration references across CLI paths (scaffolding, SDK generate/dump, sessions).
- Adds unit and end-to-end tests covering synthetic project generation and TypeScript AppHost project-reference discovery/codegen.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Aspire.Cli.Tests/TestServices/TestAppHostServerSessionFactory.cs | Updates test session factory signature to use IntegrationReference. |
| tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs | Adds unit tests for synthetic integration restore .csproj generation. |
| tests/Aspire.Cli.Tests/Projects/GuestAppHostProjectTests.cs | Updates configuration tests to validate integration reference behavior (packages + project refs). |
| tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs | Updates project scaffolding tests to pass IntegrationReference objects. |
| tests/Aspire.Cli.Tests/Configuration/IntegrationReferenceTests.cs | Adds unit tests for IntegrationReference and .csproj detection/path resolution. |
| tests/Aspire.Cli.EndToEnd.Tests/ProjectReferenceTests.cs | Adds E2E scenario validating TS AppHost can use a local .NET integration project reference. |
| src/Aspire.Cli/Scaffolding/ScaffoldingService.cs | Switches scaffolding preparation to use integration references. |
| src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs | Implements project-reference path: synthetic .csproj + dotnet build to materialize DLL closure; retains NuGet-only path. |
| src/Aspire.Cli/Projects/IAppHostServerSession.cs | Updates session factory API to accept integration references. |
| src/Aspire.Cli/Projects/IAppHostServerProject.cs | Updates server project API to accept integration references. |
| src/Aspire.Cli/Projects/GuestAppHostProject.cs | Updates integration gathering and codegen hash inputs to use integration references. |
| src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs | Updates generated server project to handle explicit project references and new integration list type. |
| src/Aspire.Cli/Projects/AppHostServerSession.cs | Wires session preparation to pass integration references. |
| src/Aspire.Cli/Projects/AppHostServerProject.cs | Updates prebuilt project construction to include SDK installer dependency. |
| src/Aspire.Cli/Configuration/IntegrationReference.cs | Adds record representing either a NuGet reference or a .csproj project reference. |
| src/Aspire.Cli/Configuration/AspireJsonConfiguration.cs | Replaces package enumeration with GetIntegrationReferences supporting .csproj detection and path resolution. |
| src/Aspire.Cli/Commands/Sdk/SdkGenerateCommand.cs | Uses IAppHostServerProject.PrepareAsync with integration references (removes concrete casting). |
| src/Aspire.Cli/Commands/Sdk/SdkDumpCommand.cs | Uses IAppHostServerProject.PrepareAsync with optional project-reference integration. |
Comments suppressed due to low confidence (2)
src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs:214
- When copying
nuget.config,appHostDirectoryis computed asPath.GetDirectoryName(_appPath)!, which points to the parent of the AppHost directory. This can cause restores to miss the user’s nuget.config. Use_appPathas the app host directory.
// Copy nuget.config from the user's apphost directory if present
var appHostDirectory = Path.GetDirectoryName(_appPath)!;
var userNugetConfig = Path.Combine(appHostDirectory, "nuget.config");
if (File.Exists(userNugetConfig))
{
File.Copy(userNugetConfig, Path.Combine(restoreDir, "nuget.config"), overwrite: true);
}
src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs:105
ResolveChannelNameAsyncis called to read the local.aspire/settings.jsonchannel, but inside it currently usesPath.GetDirectoryName(_appPath). Since_appPathis the AppHost directory, this will look in the parent directory and can ignore the app’s configured channel. UpdateResolveChannelNameAsyncto load from_appPathdirectly.
// Resolve the configured channel (local settings.json → global config fallback)
var channelName = await ResolveChannelNameAsync(cancellationToken);
🎬 CLI E2E Test RecordingsThe following terminal recordings are available for commit
📹 Recordings uploaded automatically from CI run #22659199017 |
Allow .aspire/settings.json packages entries to reference local .csproj files instead of NuGet versions. When a value ends in '.csproj', it's treated as a project reference: PrebuiltAppHostServer publishes it via dotnet publish and copies the full transitive DLL closure into the integration libs path. DotNetBasedAppHostServerProject adds ProjectReference elements to the generated csproj. Introduces IntegrationReference record type to represent both NuGet packages and project references, replacing the (Name, Version) tuple throughout IAppHostServerProject.PrepareAsync and related APIs. Fixes #14760 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the now-unused GetAllPackages methods from AspireJsonConfiguration. Update tests to use GetIntegrationReferences instead. Add test for project reference detection (.csproj paths). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ution Replace the two-step approach (BundleNuGetService restore + per-project publish) with a single synthetic .csproj that includes all PackageReferences and ProjectReferences, then dotnet publish once to get the full transitive DLL closure. Remove BundleNuGetService dependency from PrebuiltAppHostServer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore BundleNuGetService for the NuGet-only path (no SDK required). Only use dotnet publish with a synthetic project when project references are present in settings.json (requires .NET SDK). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Build the synthetic integration project with OutDir pointing directly to the libs path, eliminating the need for dotnet publish and the extra copy step. Remove PublishProjectAsync from IDotNetCliRunner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Check SDK availability before building project references and provide a clear error message if missing. Write Directory.Packages.props (CPM opt-out), Directory.Build.props, and Directory.Build.targets to the synthetic project directory to prevent parent MSBuild imports from interfering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SdkGenerateCommand and SdkDumpCommand now use IAppHostServerProject.PrepareAsync instead of casting to DotNetBasedAppHostServerProject and calling CreateProjectFilesAsync/BuildAsync directly. This means they work in both dev mode and bundle mode with project references. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SDK commands no longer reference DotNetBasedAppHostServerProject.DefaultSdkVersion. The codegen package uses VersionHelper.GetDefaultTemplateVersion() (CLI version), and Aspire.Hosting comes transitively from the integration project reference. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tests cover IntegrationReference type properties, AspireJsonConfiguration.GetIntegrationReferences detection of .csproj paths, and PrebuiltAppHostServer.GenerateIntegrationProjectFile output (PackageReference, ProjectReference, OutDir, CopyLocalLockFileAssemblies, analyzer suppression). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tests the full flow: create a .NET hosting integration with [AspireExport], create a TypeScript AppHost, add the integration as a project reference in settings.json, start the AppHost, and verify the custom addMyService method appears in the generated TypeScript SDK. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace multiline cat heredocs with C# ExecuteCallback to write the integration project files and update settings.json. Reads sdkVersion from the settings.json that aspire init creates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Null-safe value handling in GetIntegrationReferences (trim, null check before .csproj detection) - Clean stale libs directory before project ref build to prevent leftover DLLs - Use XDocument for synthetic project generation instead of string interpolation (XML-safe) - Filter SDK-only packages from ATS assembly list in DotNetBasedAppHostServerProject - Restore xmldoc param comments on PrebuiltAppHostServer constructor Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update apphost.ts to use the custom integration (addMyService), then verify with aspire wait and aspire describe that the resource actually runs. Reduce timeouts to be more reasonable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ration The MyIntegration directory is inside the workspace (./MyIntegration not ../MyIntegration). Also delete .modules/ before aspire start to force re-codegen with the new integration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NuGetConfigMerger.CreateOrUpdateAsync is a no-op for implicit/hive channels. Instead, use GetNuGetSourcesAsync to get the actual feed URLs and write a nuget.config directly into the synthetic project directory. This ensures dotnet build can resolve Aspire packages from hive feeds in CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PR #14811 removed ForceInstall from IDotNetSdkInstaller.CheckAsync, changing from 4-element to 3-element tuple. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
659ee4c to
431f132
Compare
Capture and log stdout/stderr from dotnet build when the synthetic integration project fails, to help diagnose CI failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…channel feeds When the synthetic project has ProjectReferences, MSBuild restores the referenced project's packages from nuget.config nearest to that project's directory — not the synthetic project's directory. Add RestoreConfigFile to the synthetic .csproj so all projects in the build graph use our channel-aware nuget.config. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…esolution MyIntegration.csproj needs to resolve Aspire.Hosting from the hive during dotnet build. MSBuild walks up from the project directory looking for nuget.config — without one in the workspace, it defaults to nuget.org which doesn't have prerelease versions. Write a nuget.config with hive sources in the workspace root. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PR Testing ReportCLI Version: Scenarios Tested
Key Observations
Overall: ✅ Verified — Project reference support for polyglot AppHost integrations works as expected. |
JamesNK
left a comment
There was a problem hiding this comment.
Nice PR — the IntegrationReference abstraction is clean and the two resolution paths in PrebuiltAppHostServer.PrepareAsync (NuGet-only vs project refs) are well separated. The SDK commands (SdkDumpCommand / SdkGenerateCommand) are nicely simplified by routing through the interface instead of type-checking. Tests are thorough.
Main concern is around the NuGet configuration handling in BuildIntegrationProjectAsync:
- User nuget.config overwrite: If the user has a
nuget.configand a channel is configured, the user's config is first copied then completely overwritten by the generated one. Custom sources are silently lost. RestoreConfigFileis graph-wide: This MSBuild property applies to the entire restore graph, including the referenced project's transitive dependencies. If the referenced project needs sources that aren't in the generated config, restore will fail.- Unconditional
nuget.org: Always adding nuget.org may be problematic in restricted environments.
These are related issues — recommend reconsidering the NuGet source strategy for the synthetic project. Options include: using RestoreAdditionalProjectSources instead of RestoreConfigFile, or merging channel sources into the user's existing config rather than overwriting it.
Smaller items: hardcoded net10.0 TFM (should share constant with DotNetBasedAppHostServerProject), method naming (GetAllPackagesAsync → GetAllIntegrationsAsync), and nullable safety around IntegrationReference.Version!.
|
@davidfowl Trying out AI code review 😄 |
- Add IntegrationReference validation via factory methods (FromPackage/FromProject) ensuring exactly one of Version or ProjectPath is set - Rename GetAllPackagesAsync to GetIntegrationReferencesAsync - Add explicit null check for Version instead of null-forgiving operator - Use DotNetBasedAppHostServerProject.TargetFramework constant instead of hardcoded "net10.0" in PrebuiltAppHostServer - Replace RestoreConfigFile with RestoreAdditionalProjectSources MSBuild property to add channel sources without replacing the user's NuGet config - Remove nuget.config generation with <clear/> and unconditional nuget.org addition - Stop copying/overwriting user nuget.config (RestoreAdditionalProjectSources makes this unnecessary) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Align with PrebuiltAppHostServer: replace NuGetConfigMerger with RestoreAdditionalProjectSources for channel source resolution. This is additive and propagates to the entire restore graph including project references. Update test to verify csproj contains the correct sources instead of checking nuget.config. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- IntegrationReference: change from record to class (JamesNK) - Rename 'packages' locals to 'integrations' where assigned from GetIntegrationReferencesAsync (JamesNK) - Call GetNuGetSourcesAsync unconditionally in BuildIntegrationProjectAsync (sebastienros) - Always regenerate codegen when project references are present by including timestamp in hash (sebastienros) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Can |
|
Derive assembly name from |
Add a custom MSBuild target to the synthetic project that writes resolved project reference assembly names to a file after build. Use these actual assembly names (which may differ from settings.json key or csproj filename if <AssemblyName> is overridden) for the AtsAssemblies list in appsettings.json. Move GenerateAppSettingsAsync to after build/restore in all cases for a simpler linear flow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add project reference support for polyglot apphost integrations Allow .aspire/settings.json packages entries to reference local .csproj files instead of NuGet versions. When a value ends in '.csproj', it's treated as a project reference: PrebuiltAppHostServer publishes it via dotnet publish and copies the full transitive DLL closure into the integration libs path. DotNetBasedAppHostServerProject adds ProjectReference elements to the generated csproj. Introduces IntegrationReference record type to represent both NuGet packages and project references, replacing the (Name, Version) tuple throughout IAppHostServerProject.PrepareAsync and related APIs. Fixes #14760 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove GetAllPackages, migrate tests to GetIntegrationReferences Remove the now-unused GetAllPackages methods from AspireJsonConfiguration. Update tests to use GetIntegrationReferences instead. Add test for project reference detection (.csproj paths). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use single dotnet publish for PrebuiltAppHostServer integration resolution Replace the two-step approach (BundleNuGetService restore + per-project publish) with a single synthetic .csproj that includes all PackageReferences and ProjectReferences, then dotnet publish once to get the full transitive DLL closure. Remove BundleNuGetService dependency from PrebuiltAppHostServer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Only use dotnet publish when project references are present Restore BundleNuGetService for the NuGet-only path (no SDK required). Only use dotnet publish with a synthetic project when project references are present in settings.json (requires .NET SDK). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use dotnet build with CopyLocalLockFileAssemblies instead of publish Build the synthetic integration project with OutDir pointing directly to the libs path, eliminating the need for dotnet publish and the extra copy step. Remove PublishProjectAsync from IDotNetCliRunner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add SDK check for project refs and isolate from parent MSBuild imports Check SDK availability before building project references and provide a clear error message if missing. Write Directory.Packages.props (CPM opt-out), Directory.Build.props, and Directory.Build.targets to the synthetic project directory to prevent parent MSBuild imports from interfering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove DotNetBasedAppHostServerProject casts from SDK commands SdkGenerateCommand and SdkDumpCommand now use IAppHostServerProject.PrepareAsync instead of casting to DotNetBasedAppHostServerProject and calling CreateProjectFilesAsync/BuildAsync directly. This means they work in both dev mode and bundle mode with project references. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use CLI version for SDK commands, let project deps resolve transitively SDK commands no longer reference DotNetBasedAppHostServerProject.DefaultSdkVersion. The codegen package uses VersionHelper.GetDefaultTemplateVersion() (CLI version), and Aspire.Hosting comes transitively from the integration project reference. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add unit tests for IntegrationReference and synthetic project generation Tests cover IntegrationReference type properties, AspireJsonConfiguration.GetIntegrationReferences detection of .csproj paths, and PrebuiltAppHostServer.GenerateIntegrationProjectFile output (PackageReference, ProjectReference, OutDir, CopyLocalLockFileAssemblies, analyzer suppression). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add E2E test for project reference integration support Tests the full flow: create a .NET hosting integration with [AspireExport], create a TypeScript AppHost, add the integration as a project reference in settings.json, start the AppHost, and verify the custom addMyService method appears in the generated TypeScript SDK. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify E2E test: use ExecuteCallback for file creation Replace multiline cat heredocs with C# ExecuteCallback to write the integration project files and update settings.json. Reads sdkVersion from the settings.json that aspire init creates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback - Null-safe value handling in GetIntegrationReferences (trim, null check before .csproj detection) - Clean stale libs directory before project ref build to prevent leftover DLLs - Use XDocument for synthetic project generation instead of string interpolation (XML-safe) - Filter SDK-only packages from ATS assembly list in DotNetBasedAppHostServerProject - Restore xmldoc param comments on PrebuiltAppHostServer constructor Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use using directive for System.Xml.Linq Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Improve project reference E2E test with describe/wait verification Update apphost.ts to use the custom integration (addMyService), then verify with aspire wait and aspire describe that the resource actually runs. Reduce timeouts to be more reasonable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix E2E test: use redis image instead of nonexistent myservice Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix E2E test: correct project reference path and force codegen regeneration The MyIntegration directory is inside the workspace (./MyIntegration not ../MyIntegration). Also delete .modules/ before aspire start to force re-codegen with the new integration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix: write nuget.config with channel sources for project ref builds NuGetConfigMerger.CreateOrUpdateAsync is a no-op for implicit/hive channels. Instead, use GetNuGetSourcesAsync to get the actual feed URLs and write a nuget.config directly into the synthetic project directory. This ensures dotnet build can resolve Aspire packages from hive feeds in CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CheckAsync tuple deconstruction after release/13.2 rebase PR #14811 removed ForceInstall from IDotNetSdkInstaller.CheckAsync, changing from 4-element to 3-element tuple. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add build output logging for integration project failures Capture and log stdout/stderr from dotnet build when the synthetic integration project fails, to help diagnose CI failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Dump child log on E2E test failure for CI debugging Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix: use RestoreConfigFile to ensure project references resolve from channel feeds When the synthetic project has ProjectReferences, MSBuild restores the referenced project's packages from nuget.config nearest to that project's directory — not the synthetic project's directory. Add RestoreConfigFile to the synthetic .csproj so all projects in the build graph use our channel-aware nuget.config. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix E2E test: write nuget.config in workspace for project reference resolution MyIntegration.csproj needs to resolve Aspire.Hosting from the hive during dotnet build. MSBuild walks up from the project directory looking for nuget.config — without one in the workspace, it defaults to nuget.org which doesn't have prerelease versions. Write a nuget.config with hive sources in the workspace root. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address JamesNK review feedback - Add IntegrationReference validation via factory methods (FromPackage/FromProject) ensuring exactly one of Version or ProjectPath is set - Rename GetAllPackagesAsync to GetIntegrationReferencesAsync - Add explicit null check for Version instead of null-forgiving operator - Use DotNetBasedAppHostServerProject.TargetFramework constant instead of hardcoded "net10.0" in PrebuiltAppHostServer - Replace RestoreConfigFile with RestoreAdditionalProjectSources MSBuild property to add channel sources without replacing the user's NuGet config - Remove nuget.config generation with <clear/> and unconditional nuget.org addition - Stop copying/overwriting user nuget.config (RestoreAdditionalProjectSources makes this unnecessary) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use RestoreAdditionalProjectSources in DotNetBasedAppHostServerProject Align with PrebuiltAppHostServer: replace NuGetConfigMerger with RestoreAdditionalProjectSources for channel source resolution. This is additive and propagates to the entire restore graph including project references. Update test to verify csproj contains the correct sources instead of checking nuget.config. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address JamesNK and sebastienros review feedback - IntegrationReference: change from record to class (JamesNK) - Rename 'packages' locals to 'integrations' where assigned from GetIntegrationReferencesAsync (JamesNK) - Call GetNuGetSourcesAsync unconditionally in BuildIntegrationProjectAsync (sebastienros) - Always regenerate codegen when project references are present by including timestamp in hash (sebastienros) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Resolve project ref assembly names from MSBuild build output Add a custom MSBuild target to the synthetic project that writes resolved project reference assembly names to a file after build. Use these actual assembly names (which may differ from settings.json key or csproj filename if <AssemblyName> is overridden) for the AtsAssemblies list in appsettings.json. Move GenerateAppSettingsAsync to after build/restore in all cases for a simpler linear flow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Description
Adds project reference support for polyglot AppHost integrations, enabling integration authors to test hosting integrations locally before publishing to a NuGet feed.
How it works
In
.aspire/settings.json, a package entry whose value ends in.csprojis treated as a project reference instead of a NuGet version:{ "packages": { "Aspire.Hosting.Redis": "13.2.0", "MyIntegration": "../src/MyIntegration/MyIntegration.csproj" } }Two resolution paths in
PrebuiltAppHostServer.PrepareAsync:BundleNuGetService— no .NET SDK required.csprojwith<PackageReference>and<ProjectReference>items, runsdotnet buildwithCopyLocalLockFileAssemblies=trueto produce the full transitive DLL closure directly into the integration libs path. Requires .NET SDK (checked before build).The synthetic project is isolated from parent MSBuild imports via
Directory.Build.props,Directory.Build.targets, andDirectory.Packages.props(CPM opt-out).Key changes
IntegrationReferencerecord: represents both NuGet packages and project referencesAspireJsonConfiguration.GetIntegrationReferences(): replacesGetAllPackages(), detects.csprojpathsIAppHostServerProject.PrepareAsync: signature changed toIEnumerable<IntegrationReference>PrebuiltAppHostServer: NuGet-only →BundleNuGetService; project refs →dotnet buildsynthetic projectDotNetBasedAppHostServerProject: handles project refs as<ProjectReference>in generated csprojSdkGenerateCommand/SdkDumpCommand: usePrepareAsyncthrough interface (no more casting)Fixes #14760
Checklist
<remarks />and<code />elements on your triple slash comments?aspire.devissue: