Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 2, 2025

The test infrastructure assigns the root service provider to HttpContext.RequestServices, causing InvalidOperationException when resolving scoped services like IViewBufferScope in environments with strict DI validation (.NET 8+). This fails 66/166 tests on Ubuntu 24.04 with .NET 8.0.21.

Changes

  • Create service scope with app.Services.CreateScope() and assign to RequestServices
  • Use scoped provider for ActivatorUtilities.CreateInstance<RazorView>()
  • Properly dispose scope with using statement
// Before
var httpContext = new DefaultHttpContext
{
    RequestServices = app.Services  // ❌ Root provider
};

// After
using var scope = app.Services.CreateScope();
var httpContext = new DefaultHttpContext
{
    RequestServices = scope.ServiceProvider  // ✅ Scoped provider
};

Aligns with ASP.NET Core DI lifetime semantics.

Original prompt

This section details on the original issue you should resolve

<issue_title>DI Scoping Bug in RazorSourceGeneratorTestsBase Causes Test Failures</issue_title>
<issue_description># DI Scoping Bug in RazorSourceGeneratorTestsBase Causes Test Failures

Summary

The Microsoft.NET.Sdk.Razor.SourceGenerators.Test test suite fails with 66 out of 166 tests (40%) throwing InvalidOperationException: Cannot resolve scoped service 'Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.IViewBufferScope' from root provider due to improper dependency injection scoping in the test infrastructure.

Environment

Steps to Reproduce

  1. Clone the repository
  2. Run ./restore.sh
  3. Run ./build.sh -test
  4. Observe test failures in Microsoft.NET.Sdk.Razor.SourceGenerators.Test

Expected Behavior

All 166 tests should pass.

Actual Behavior

66 tests fail with:

System.InvalidOperationException : Cannot resolve scoped service 'Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.IViewBufferScope' from root provider.

Example Stack Trace

at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(ServiceCallSite callSite, IServiceScope scope, IServiceScope rootScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.OnResolve(ServiceCallSite callSite, IServiceScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGeneratorTestsBase.RenderRazorPageAsync(Compilation compilation, String name)

Test Results

Before fix:

Microsoft.NET.Sdk.Razor.SourceGenerators.Test  Total: 166, Errors: 0, Failed: 66, Skipped: 0, Time: 576.302s

After fix:

Microsoft.NET.Sdk.Razor.SourceGenerators.Test succeeded (7.1s)

Root Cause

In src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/RazorSourceGeneratorTestsBase.cs at line 155, the test code assigns the root service provider to HttpContext.RequestServices:

var app = appBuilder.Build();
var httpContext = new DefaultHttpContext
{
    RequestServices = app.Services  // ❌ Root provider
};

When RazorView.RenderAsync() executes (line 190), it attempts to resolve IViewBufferScope, which is registered as a scoped service in ASP.NET Core MVC. ASP.NET Core's dependency injection validation (enabled in .NET 8+) correctly prevents resolving scoped services from the root provider.

Solution

Create a service scope before assigning to RequestServices:

var app = appBuilder.Build();
var httpContext = new DefaultHttpContext
{
    RequestServices = app.Services.CreateScope().ServiceProvider  // ✅ Scoped provider
};

Fix

File: src/Compiler/test/Microsoft.NET.Sdk.Razor.SourceGenerators.Tests/RazorSourceGeneratorTestsBase.cs
Line: 155

Before:

RequestServices = app.Services

After:

RequestServices = app.Services.CreateScope().ServiceProvider

This one-line change fixes all 66 failing tests by properly adhering to ASP.NET Core's DI scoping rules.

Additional Context

  • This issue may not reproduce in CI if the CBL-Mariner 2.0 container uses an older .NET runtime with less strict DI validation
  • The issue manifests on Ubuntu 24.04 with .NET 8.0.21 runtime
  • The fix aligns with ASP.NET Core best practices and Microsoft's own DI documentation
  • No other code changes are required

Impact

  • Current: 66 tests fail on non-container Linux environments
  • After Fix: All 166 tests pass
  • Risk: Low - the change properly scopes the service provider as intended by ASP.NET Core's design

References

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

@davidwengier This one I've never seen fail in any local run or CI, that I can recall. Curious to know more about the process for creating these issues @StevenTCramer if you can share? @davidwengier Interesting. I wonder why this one doesn't fail for us? There are certainly differences between WSL and a "real" Ubuntu machine we do CI on, but I wouldn't have thought any of them would have had any effect on this.

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

Copilot AI and others added 2 commits November 2, 2025 06:09
- Create scoped service provider instead of using root provider
- Update both RequestServices and ActivatorUtilities.CreateInstance to use scoped provider
- Properly dispose scope with using statement

This fixes test failures in environments with stricter DI validation and aligns with ASP.NET Core best practices.

Co-authored-by: davidwengier <[email protected]>
Add comment explaining why service scope is necessary to handle scoped services properly and avoid DI validation issues.

Co-authored-by: davidwengier <[email protected]>
Copilot AI changed the title [WIP] Fix DI scoping bug in RazorSourceGeneratorTestsBase Fix DI scoping violation in RazorSourceGeneratorTestsBase Nov 2, 2025
Copilot AI requested a review from davidwengier November 2, 2025 06:40
Copilot finished work on behalf of davidwengier November 2, 2025 06:40
Copy link
Member

@davidwengier davidwengier left a comment

Choose a reason for hiding this comment

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

I've not seen this fail, but I'm happy to believe it did

@davidwengier davidwengier marked this pull request as ready for review November 2, 2025 07:25
@davidwengier davidwengier requested a review from a team as a code owner November 2, 2025 07:25
Copy link
Contributor

@ToddGrun ToddGrun left a comment

Choose a reason for hiding this comment

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

:shipit:

@davidwengier davidwengier merged commit 191feab into main Nov 2, 2025
11 checks passed
@davidwengier davidwengier deleted the copilot/fix-di-scoping-bug branch November 2, 2025 18:04
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Nov 2, 2025
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.

DI Scoping Bug in RazorSourceGeneratorTestsBase Causes Test Failures

3 participants