Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,13 @@ internal static class DiagnosticDescriptors
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
helpLinkUri: "https://aka.ms/aspnet/analyzers");

internal static readonly DiagnosticDescriptor DisallowConfigureAppConfigureHostBuilder = new(
"ASP0013",
"Suggest using WebApplicationBuilder.Configuration over Configure methods",
"Suggest using WebApplicationBuilder.Configuration instead of {0}",
"Usage",
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
helpLinkUri: "https://aka.ms/aspnet/analyzers");
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public class WebApplicationBuilderAnalyzer : DiagnosticAnalyzer
DiagnosticDescriptors.DoNotUseConfigureWebHostWithConfigureHostBuilder,
DiagnosticDescriptors.DoNotUseConfigureWithConfigureWebHostBuilder,
DiagnosticDescriptors.DoNotUseUseStartupWithConfigureWebHostBuilder,
DiagnosticDescriptors.DoNotUseHostConfigureLogging
DiagnosticDescriptors.DoNotUseHostConfigureLogging,
DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder
});

public override void Initialize(AnalysisContext context)
Expand Down Expand Up @@ -50,6 +51,14 @@ public override void Initialize(AnalysisContext context)
wellKnownTypes.HostingHostBuilderExtensions,
wellKnownTypes.WebHostBuilderExtensions
};
INamedTypeSymbol[] configureAppTypes =
{
wellKnownTypes.ConfigureHostBuilder,
wellKnownTypes.ConfigureWebHostBuilder,
wellKnownTypes.WebHostBuilderExtensions,
wellKnownTypes.HostingHostBuilderExtensions,
};
INamedTypeSymbol[] configureHostTypes = { wellKnownTypes.ConfigureHostBuilder };

compilationStartAnalysisContext.RegisterOperationAction(operationAnalysisContext =>
{
Expand Down Expand Up @@ -103,7 +112,7 @@ public override void Initialize(AnalysisContext context)
DiagnosticDescriptors.DoNotUseUseStartupWithConfigureWebHostBuilder,
invocation));
}

//var builder = WebApplication.CreateBuilder(args);
//builder.Host.ConfigureLogging(x => {})
if (IsDisallowedMethod(
Expand Down Expand Up @@ -135,6 +144,54 @@ public override void Initialize(AnalysisContext context)
DiagnosticDescriptors.DoNotUseHostConfigureLogging,
invocation));
}

// var builder = WebApplication.CreateBuilder();
// builder.WebHost.ConfigureAppConfiguration(builder => {});
if (IsDisallowedMethod(
operationAnalysisContext,
invocation,
targetMethod,
wellKnownTypes.ConfigureWebHostBuilder,
"ConfigureAppConfiguration",
configureAppTypes))
{
operationAnalysisContext.ReportDiagnostic(
CreateDiagnostic(
DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder,
invocation));
}

// var builder = WebApplication.CreateBuilder();
// builder.Host.ConfigureAppConfiguration(builder => {});
if (IsDisallowedMethod(
operationAnalysisContext,
invocation,
targetMethod,
wellKnownTypes.ConfigureHostBuilder,
"ConfigureAppConfiguration",
configureAppTypes))
{
operationAnalysisContext.ReportDiagnostic(
CreateDiagnostic(
DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder,
invocation));
}

// var builder = WebApplication.CreateBuilder();
// builder.Host.ConfigureHostConfiguration(builder => {});
if (IsDisallowedMethod(
operationAnalysisContext,
invocation,
targetMethod,
wellKnownTypes.ConfigureHostBuilder,
"ConfigureHostConfiguration",
configureHostTypes))
{
operationAnalysisContext.ReportDiagnostic(
CreateDiagnostic(
DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder,
invocation));
}

static Diagnostic CreateDiagnostic(DiagnosticDescriptor descriptor, IInvocationOperation operation)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Globalization;
using Microsoft.AspNetCore.Analyzer.Testing;

namespace Microsoft.AspNetCore.Analyzers.WebApplicationBuilder;
public partial class DisallowConfigureAppConfigureHostBuilderTest
{
private TestDiagnosticAnalyzerRunner Runner { get; } = new(new WebApplicationBuilderAnalyzer());

[Fact]
public async Task ConfigurationBuilderRunsWithoutDiagnostic()
{
// Arrange
var source = @"
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile(""foo.json"", optional: true);
";
// Act
var diagnostic = await Runner.GetDiagnosticsAsync(source);

// Assert
Assert.Empty(diagnostic);
}

[Fact]
public async Task ConfigureAppHostBuilderProducesDiagnostic()
{
// Arrange
var source = TestSource.Read(@"
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Host./*MM*/ConfigureAppConfiguration(builder =>
{
builder.AddJsonFile(""foo.json"", optional: true);
});
");

// Act
var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);

// Assert
var diagnostic = Assert.Single(diagnostics);
Assert.Same(DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, diagnostic.Descriptor);
AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
Assert.Equal("Suggest using WebApplicationBuilder.Configuration instead of ConfigureAppConfiguration", diagnostic.GetMessage(CultureInfo.InvariantCulture));
}

[Fact]
public async Task ConfigureHostHostBuilderProducesDiagnostic()
{
// Arrange
var source = TestSource.Read(@"
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Host./*MM*/ConfigureHostConfiguration(builder =>
{
builder.AddJsonFile(""foo.json"", optional: true);
});
");

// Act
var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);

// Assert
var diagnostic = Assert.Single(diagnostics);
Assert.Same(DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, diagnostic.Descriptor);
AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
Assert.Equal("Suggest using WebApplicationBuilder.Configuration instead of ConfigureHostConfiguration", diagnostic.GetMessage(CultureInfo.InvariantCulture));
}

[Fact]
public async Task ConfigureAppWebHostBuilderProducesDiagnostic()
{
// Arrange
var source = TestSource.Read(@"
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost./*MM*/ConfigureAppConfiguration(builder =>
{
builder.AddJsonFile(""foo.json"", optional: true);
});
");

// Act
var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);

// Assert
var diagnostic = Assert.Single(diagnostics);
Assert.Same(DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, diagnostic.Descriptor);
AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
Assert.Equal("Suggest using WebApplicationBuilder.Configuration instead of ConfigureAppConfiguration", diagnostic.GetMessage(CultureInfo.InvariantCulture));
}

[Fact]
public async Task ConfigureAppWebHostBuilderWithContextProducesDiagnostic()
{
// Arrange
var source = TestSource.Read(@"
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost./*MM*/ConfigureAppConfiguration((context, webHostBuilder) => { });
");

// Act
var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);

// Assert
var diagnostic = Assert.Single(diagnostics);
Assert.Same(DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, diagnostic.Descriptor);
AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
Assert.Equal("Suggest using WebApplicationBuilder.Configuration instead of ConfigureAppConfiguration", diagnostic.GetMessage(CultureInfo.InvariantCulture));
}
[Fact]
public async Task ConfigureAppWebHostBuilderProducesDiagnosticInMain()
{
// Arrange
var source = TestSource.Read(@"
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
public static class Test
{
public static void Main(string[]args) {
var builder = WebApplication.CreateBuilder(args);
builder.WebHost./*MM*/ConfigureAppConfiguration(builder => { });
}
}
");

// Act
var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);

// Assert
var diagnostic = Assert.Single(diagnostics);
Assert.Same(DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, diagnostic.Descriptor);
AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
Assert.Equal("Suggest using WebApplicationBuilder.Configuration instead of ConfigureAppConfiguration", diagnostic.GetMessage(CultureInfo.InvariantCulture));
}
[Fact]
public async Task ConfigureAppWebHostOnBuilderProducesDiagnosticInMain()
{
// Arrange
var source = TestSource.Read(@"
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
public static class Test
{
public static void Main(string[]args) {
var builder = WebApplication.CreateBuilder(args);
var webhost = builder.WebHost;
webhost./*MM*/ConfigureAppConfiguration(builder => { });
}
}
");

// Act
var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);

// Assert
var diagnostic = Assert.Single(diagnostics);
Assert.Same(DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, diagnostic.Descriptor);
AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
Assert.Equal("Suggest using WebApplicationBuilder.Configuration instead of ConfigureAppConfiguration", diagnostic.GetMessage(CultureInfo.InvariantCulture));
}
[Fact]
public async Task TwoInvocationsProduceTwoDiagnostic()
{
// Arrange
var source = TestSource.Read(@"
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Host./*MM1*/ConfigureHostConfiguration(builder =>
{
builder.AddJsonFile(""foo.json"", optional: true);
});
builder.WebHost./*MM2*/ConfigureAppConfiguration(builder =>
{
builder.AddJsonFile(""foo.json"", optional: true);
});
");

// Act
var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);

// Assert
Assert.Equal(2, diagnostics.Length);
var diagnostic1 = diagnostics[0];
var diagnostic2 = diagnostics[1];
Assert.Same(DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, diagnostic1.Descriptor);
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM1"], diagnostic1.Location);
Assert.Equal("Suggest using WebApplicationBuilder.Configuration instead of ConfigureHostConfiguration", diagnostic1.GetMessage(CultureInfo.InvariantCulture));
Assert.Same(DiagnosticDescriptors.DisallowConfigureAppConfigureHostBuilder, diagnostic2.Descriptor);
AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM2"], diagnostic2.Location);
Assert.Equal("Suggest using WebApplicationBuilder.Configuration instead of ConfigureAppConfiguration", diagnostic2.GetMessage(CultureInfo.InvariantCulture));
}
}
1 change: 0 additions & 1 deletion src/Http/samples/MinimalSample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
Username: {Environment.UserName}
Date and Time: {DateTime.Now}
""");

var outer = app.MapGroup("/outer");
var inner = outer.MapGroup("/inner");

Expand Down