ClassAnalyzers.GetProjectInfo currently performs more work than its API suggests:
- Initializes MSBuild and creates a lazy
CodeService.
- Evaluates project capabilities in-process.
- Constructs
ProjectInfo, whose constructor calls TargetFrameworkHelpers and synchronously launches MSBuild subprocesses to discover and validate target frameworks.
For a typical single-target project, this means one in-process evaluation plus two CLI evaluations. Multi-targeted projects require additional framework checks. This is a likely source of startup latency; individual costs have not yet been measured.
Proposed direction
- Make
ProjectInfo a data object with no project evaluation or subprocess work in its constructor.
- Introduce one explicit project-inspection operation that obtains capabilities and framework information together.
- Reuse that result within the scaffolding operation instead of re-querying it during later preparation or template selection.
- Preserve multi-targeting compatibility rules, explicit evaluation failures, and correct SDK selection. The existing permissive
GetLowestTargetFramework path is not an equivalent replacement.
- Prefer a correctly configured in-process evaluation where feasible. If the required SDK cannot be hosted by the scaffolder runtime, batch CLI queries rather than forcing in-process evaluation.
Measure evaluation/process counts and elapsed time before and after, with focused coverage for single-target, multi-target, SDK-selection, and invalid-project cases. Avoid long-lived caches that become stale after project changes.
Keep this separate from #3836. Coordinate the project-preparation boundary with the restore/semantic-analysis follow-up in #3856.
ClassAnalyzers.GetProjectInfocurrently performs more work than its API suggests:CodeService.ProjectInfo, whose constructor callsTargetFrameworkHelpersand synchronously launches MSBuild subprocesses to discover and validate target frameworks.For a typical single-target project, this means one in-process evaluation plus two CLI evaluations. Multi-targeted projects require additional framework checks. This is a likely source of startup latency; individual costs have not yet been measured.
Proposed direction
ProjectInfoa data object with no project evaluation or subprocess work in its constructor.GetLowestTargetFrameworkpath is not an equivalent replacement.Measure evaluation/process counts and elapsed time before and after, with focused coverage for single-target, multi-target, SDK-selection, and invalid-project cases. Avoid long-lived caches that become stale after project changes.
Keep this separate from #3836. Coordinate the project-preparation boundary with the restore/semantic-analysis follow-up in #3856.