Skip to content

Obsolete RazorRuntimeCompilation #62793

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts;
/// <summary>
/// Static class that adds methods to <see cref="AssemblyPart"/>.
/// </summary>
[Obsolete("Razor runtime compilation is obsolete and is not recommended for production scenarios. For production scenarios, use the default build time compilation. For development scenarios, use Hot Reload instead. For more information, visit https://aka.ms/aspnet/deprecate/003.", DiagnosticId = "ASPDEPR003")]
public static class AssemblyPartExtensions
{
/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

namespace Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation;

#pragma warning disable ASPDEPR003 // Type or member is obsolete
internal sealed class MvcRazorRuntimeCompilationOptionsSetup : IConfigureOptions<MvcRazorRuntimeCompilationOptions>
Copy link
Member

Choose a reason for hiding this comment

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

Are you thinking we'll suppress the warning and only remove these references once the types are removed?

Asking because I was looking at deprecating IActionContextAccessor and it's much easier if we don't remove our own use of the API during the obsoletion. It does mean we have to pay that cost later when we actually remove these types.

Copy link
Member Author

@BrennanConroy BrennanConroy Jul 18, 2025

Choose a reason for hiding this comment

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

This specific usage is an internal implementation detail of the feature we're deprecating. But I think the general idea is that we keep implementation and tests specific to the feature around and move anything that can be moved onto the new feature.

#pragma warning restore ASPDEPR003 // Type or member is obsolete
{
private readonly IWebHostEnvironment _hostingEnvironment;

Expand All @@ -15,7 +17,9 @@ public MvcRazorRuntimeCompilationOptionsSetup(IWebHostEnvironment hostingEnviron
_hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment));
}

#pragma warning disable ASPDEPR003 // Type or member is obsolete
public void Configure(MvcRazorRuntimeCompilationOptions options)
#pragma warning restore ASPDEPR003 // Type or member is obsolete
{
ArgumentNullException.ThrowIfNull(options);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Microsoft.Extensions.DependencyInjection;
/// <summary>
/// Static class that adds razor compilation extension methods.
/// </summary>
[Obsolete("Razor runtime compilation is obsolete and is not recommended for production scenarios. For production scenarios, use the default build time compilation. For development scenarios, use Hot Reload instead. For more information, visit https://aka.ms/aspnet/deprecate/003.", DiagnosticId = "ASPDEPR003")]
public static class RazorRuntimeCompilationMvcBuilderExtensions
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Microsoft.Extensions.DependencyInjection;
/// <summary>
/// Static class that adds razor runtime compilation extension methods.
/// </summary>
[Obsolete("Razor runtime compilation is obsolete and is not recommended for production scenarios. For production scenarios, use the default build time compilation. For development scenarios, use Hot Reload instead. For more information, visit https://aka.ms/aspnet/deprecate/003.", DiagnosticId = "ASPDEPR003")]
public static class RazorRuntimeCompilationMvcCoreBuilderExtensions
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public override RazorProjectItem GetItem(string path, string? fileKind)
path = NormalizeAndEnsureValidPath(path);
var fileInfo = FileProvider.GetFileInfo(path);

#pragma warning disable ASPDEPR003 // Type or member is obsolete
return new FileProviderRazorProjectItem(fileInfo, basePath: string.Empty, filePath: path, root: _hostingEnvironment.ContentRootPath, fileKind);
#pragma warning restore ASPDEPR003 // Type or member is obsolete
}

public override IEnumerable<RazorProjectItem> EnumerateItems(string path)
Expand Down Expand Up @@ -63,7 +65,9 @@ private IEnumerable<RazorProjectItem> EnumerateFiles(IDirectoryContents director
{
var filePath = prefix + "/" + fileInfo.Name;

#pragma warning disable ASPDEPR003 // Type or member is obsolete
yield return new FileProviderRazorProjectItem(fileInfo, basePath, filePath: filePath, root: _hostingEnvironment.ContentRootPath);
#pragma warning restore ASPDEPR003 // Type or member is obsolete
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation;
/// <summary>
/// A file provider <see cref="RazorProjectItem"/>.
/// </summary>
[Obsolete("Razor runtime compilation is obsolete and is not recommended for production scenarios. For production scenarios, use the default build time compilation. For development scenarios, use Hot Reload instead. For more information, visit https://aka.ms/aspnet/deprecate/003.", DiagnosticId = "ASPDEPR003")]
public class FileProviderRazorProjectItem : RazorProjectItem
{
private readonly string _root;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation;
/// <summary>
/// Used to configure razor compilation.
/// </summary>
[Obsolete("Razor runtime compilation is obsolete and is not recommended for production scenarios. For production scenarios, use the default build time compilation. For development scenarios, use Hot Reload instead. For more information, visit https://aka.ms/aspnet/deprecate/003.", DiagnosticId = "ASPDEPR003")]
public class MvcRazorRuntimeCompilationOptions
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ internal class RazorReferenceManager
#pragma warning restore CA1852 // Seal internal types
{
private readonly ApplicationPartManager _partManager;
#pragma warning disable ASPDEPR003 // Type or member is obsolete
private readonly MvcRazorRuntimeCompilationOptions _options;
#pragma warning restore ASPDEPR003 // Type or member is obsolete
private object _compilationReferencesLock = new object();
private bool _compilationReferencesInitialized;
private IReadOnlyList<MetadataReference>? _compilationReferences;

public RazorReferenceManager(
ApplicationPartManager partManager,
#pragma warning disable ASPDEPR003 // Type or member is obsolete
IOptions<MvcRazorRuntimeCompilationOptions> options)
#pragma warning restore ASPDEPR003 // Type or member is obsolete
{
_partManager = partManager;
_options = options.Value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ internal sealed class RazorRuntimeCompilationHostingStartup : IHostingStartup
public void Configure(IWebHostBuilder builder)
{
// Add Razor services
#pragma warning disable ASPDEPR003 // Type or member is obsolete
builder.ConfigureServices(RazorRuntimeCompilationMvcCoreBuilderExtensions.AddServices);
#pragma warning restore ASPDEPR003 // Type or member is obsolete
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation;

internal sealed class RuntimeCompilationFileProvider
{
#pragma warning disable ASPDEPR003 // Type or member is obsolete
private readonly MvcRazorRuntimeCompilationOptions _options;
#pragma warning restore ASPDEPR003 // Type or member is obsolete
private IFileProvider? _compositeFileProvider;

#pragma warning disable ASPDEPR003 // Type or member is obsolete
public RuntimeCompilationFileProvider(IOptions<MvcRazorRuntimeCompilationOptions> options)
#pragma warning restore ASPDEPR003 // Type or member is obsolete
{
ArgumentNullException.ThrowIfNull(options);

Expand All @@ -31,15 +35,19 @@ public IFileProvider FileProvider
}
}

#pragma warning disable ASPDEPR003 // Type or member is obsolete
private static IFileProvider GetCompositeFileProvider(MvcRazorRuntimeCompilationOptions options)
#pragma warning restore ASPDEPR003 // Type or member is obsolete
{
var fileProviders = options.FileProviders;
if (fileProviders.Count == 0)
{
#pragma warning disable ASPDEPR003 // Type or member is obsolete
var message = Resources.FormatFileProvidersAreRequired(
typeof(MvcRazorRuntimeCompilationOptions).FullName,
nameof(MvcRazorRuntimeCompilationOptions.FileProviders),
typeof(IFileProvider).FullName);
#pragma warning restore ASPDEPR003 // Type or member is obsolete
throw new InvalidOperationException(message);
}
else if (fileProviders.Count == 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ public void AddServices_ReplacesRazorViewCompiler()
.AddSingleton<IViewCompilerProvider, DefaultViewCompilerProvider>();

// Act
#pragma warning disable ASPDEPR003 // Type or member is obsolete
RazorRuntimeCompilationMvcCoreBuilderExtensions.AddServices(services);
#pragma warning restore ASPDEPR003 // Type or member is obsolete

// Assert
var serviceDescriptor = Assert.Single(services, service => service.ServiceType == typeof(IViewCompilerProvider));
Expand All @@ -34,7 +36,9 @@ public void AddServices_ReplacesActionDescriptorProvider()
.AddSingleton<IActionDescriptorProvider, CompiledPageActionDescriptorProvider>();

// Act
#pragma warning disable ASPDEPR003 // Type or member is obsolete
RazorRuntimeCompilationMvcCoreBuilderExtensions.AddServices(services);
#pragma warning restore ASPDEPR003 // Type or member is obsolete

// Assert
var serviceDescriptor = Assert.Single(services, service => service.ServiceType == typeof(IActionDescriptorProvider));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,12 @@ private static FileProviderRazorProjectFileSystem GetRazorProjectFileSystem(
TestFileProvider fileProvider,
string contentRootPath = "BasePath")
{
#pragma warning disable ASPDEPR003 // Type or member is obsolete
var options = Options.Create(new MvcRazorRuntimeCompilationOptions
{
FileProviders = { fileProvider }
});
#pragma warning restore ASPDEPR003 // Type or member is obsolete
var compilationFileProvider = new RuntimeCompilationFileProvider(options);
var fileSystem = new FileProviderRazorProjectFileSystem(
compilationFileProvider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ public class RazorReferenceManagerTest
public void GetCompilationReferences_CombinesApplicationPartAndOptionMetadataReferences()
{
// Arrange
#pragma warning disable ASPDEPR003 // Type or member is obsolete
var options = new MvcRazorRuntimeCompilationOptions();
#pragma warning restore ASPDEPR003 // Type or member is obsolete
var additionalReferencePath = "additional-path";
options.AdditionalReferencePaths.Add(additionalReferencePath);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ public class RuntimeCompilationFileProviderTest
public void GetFileProvider_ThrowsIfNoConfiguredFileProviders()
{
// Arrange
#pragma warning disable ASPDEPR003 // Type or member is obsolete
var expected =
$"'{typeof(MvcRazorRuntimeCompilationOptions).FullName}.{nameof(MvcRazorRuntimeCompilationOptions.FileProviders)}' must " +
$"not be empty. At least one '{typeof(IFileProvider).FullName}' is required to locate a view for " +
"rendering.";
var options = Options.Create(new MvcRazorRuntimeCompilationOptions());
#pragma warning restore ASPDEPR003 // Type or member is obsolete

var fileProvider = new RuntimeCompilationFileProvider(options);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -824,10 +824,12 @@ private static TestRazorViewCompiler GetViewCompiler(
CSharpCompiler csharpCompiler = null)
{
fileProvider = fileProvider ?? new TestFileProvider();
#pragma warning disable ASPDEPR003 // Type or member is obsolete
var options = Options.Create(new MvcRazorRuntimeCompilationOptions
{
FileProviders = { fileProvider }
});
#pragma warning restore ASPDEPR003 // Type or member is obsolete
var compilationFileProvider = new RuntimeCompilationFileProvider(options);

referenceManager = referenceManager ?? CreateReferenceManager();
Expand Down Expand Up @@ -855,7 +857,9 @@ private static RazorReferenceManager CreateReferenceManager()
var assembly = typeof(RuntimeViewCompilerTest).Assembly;
applicationPartManager.ApplicationParts.Add(new AssemblyPart(assembly));

#pragma warning disable ASPDEPR003 // Type or member is obsolete
return new RazorReferenceManager(applicationPartManager, Options.Create(new MvcRazorRuntimeCompilationOptions()));
#pragma warning restore ASPDEPR003 // Type or member is obsolete
}

private class TestRazorViewCompiler : RuntimeViewCompiler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ internal class TestRazorReferenceManager : RazorReferenceManager
public TestRazorReferenceManager()
: base(
new ApplicationPartManager(),
#pragma warning disable ASPDEPR003 // Type or member is obsolete
Options.Create(new MvcRazorRuntimeCompilationOptions()))
#pragma warning restore ASPDEPR003 // Type or member is obsolete
{
CompilationReferences = Array.Empty<MetadataReference>();
}
Expand Down
4 changes: 4 additions & 0 deletions src/Mvc/test/Mvc.FunctionalTests/ErrorPageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ public async Task CompilationFailuresAreListedByErrorPageMiddleware()
{
// Arrange
var factory = Factory.WithWebHostBuilder(b => b.UseStartup<ErrorPageMiddlewareWebSite.Startup>());
#pragma warning disable ASPDEPR003 // Type or member is obsolete
factory = factory.WithWebHostBuilder(b => b.ConfigureTestServices(serviceCollection => serviceCollection.Configure<MvcRazorRuntimeCompilationOptions>(ConfigureRuntimeCompilationOptions)));
#pragma warning restore ASPDEPR003 // Type or member is obsolete

var client = factory.CreateDefaultClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
Expand All @@ -70,6 +72,7 @@ public async Task CompilationFailuresAreListedByErrorPageMiddleware()
Assert.Contains(expected, content);
Assert.DoesNotContain(PreserveCompilationContextMessage, content);

#pragma warning disable ASPDEPR003 // Type or member is obsolete
static void ConfigureRuntimeCompilationOptions(MvcRazorRuntimeCompilationOptions options)
{
options.AdditionalReferencePaths.Add(typeof(string).Assembly.Location);
Expand All @@ -81,6 +84,7 @@ static void ConfigureRuntimeCompilationOptions(MvcRazorRuntimeCompilationOptions
options.AdditionalReferencePaths.Add(path);
}
}
#pragma warning restore ASPDEPR003 // Type or member is obsolete
}

[Fact]
Expand Down
2 changes: 2 additions & 0 deletions src/Mvc/test/Mvc.FunctionalTests/RazorBuildTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class RazorBuildTest : LoggedTest
protected override void Initialize(TestContext context, MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper)
{
base.Initialize(context, methodInfo, testMethodArguments, testOutputHelper);
#pragma warning disable ASPDEPR003 // Type or member is obsolete
Factory = new MvcTestFixture<RazorBuildWebSite.Startup>(LoggerFactory)
.WithWebHostBuilder(b => b.ConfigureTestServices(serviceCollection => serviceCollection.Configure<MvcRazorRuntimeCompilationOptions>(ConfigureRuntimeCompilationOptions)));

Expand All @@ -36,6 +37,7 @@ static void ConfigureRuntimeCompilationOptions(MvcRazorRuntimeCompilationOptions
options.AdditionalReferencePaths.Add(path);
}
}
#pragma warning restore ASPDEPR003 // Type or member is obsolete
Client = Factory.CreateDefaultClient();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class RazorRuntimeCompilationHostingStartupTest : LoggedTest
protected override void Initialize(TestContext context, MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper)
{
base.Initialize(context, methodInfo, testMethodArguments, testOutputHelper);
#pragma warning disable ASPDEPR003 // Type or member is obsolete
Factory = new MvcTestFixture<RazorBuildWebSite.StartupWithHostingStartup>(LoggerFactory)
.WithWebHostBuilder(b => b.UseStartup<RazorBuildWebSite.StartupWithHostingStartup>())
.WithWebHostBuilder(b => b.ConfigureTestServices(serviceCollection => serviceCollection.Configure<MvcRazorRuntimeCompilationOptions>(ConfigureRuntimeCompilationOptions)));
Expand All @@ -34,6 +35,7 @@ static void ConfigureRuntimeCompilationOptions(MvcRazorRuntimeCompilationOptions
options.AdditionalReferencePaths.Add(path);
}
}
#pragma warning restore ASPDEPR003 // Type or member is obsolete
Client = Factory.CreateDefaultClient();
}

Expand Down
Loading