diff --git a/src/Analyzers/Analyzers/src/BuildServiceProviderAnalyzer.cs b/src/Analyzers/Analyzers/src/BuildServiceProviderAnalyzer.cs
index 8ea1ffe28eb48ff6269a15966f125cf680303ac0..d50ad53a500ebc58eb5eef52dee73edff859fea7 100644
--- a/src/Analyzers/Analyzers/src/BuildServiceProviderAnalyzer.cs
+++ b/src/Analyzers/Analyzers/src/BuildServiceProviderAnalyzer.cs
@@ -19,7 +19,6 @@ namespace Microsoft.AspNetCore.Analyzers
         public void AnalyzeSymbol(SymbolAnalysisContext context)
         {
             Debug.Assert(context.Symbol.Kind == SymbolKind.NamedType);
-            Debug.Assert(StartupFacts.IsStartupClass(_context.StartupSymbols, (INamedTypeSymbol)context.Symbol));
 
             var type = (INamedTypeSymbol)context.Symbol;
 
diff --git a/src/Analyzers/Analyzers/src/StartupAnalyzer.cs b/src/Analyzers/Analyzers/src/StartupAnalyzer.cs
index fa857b89661863b73b167b241d352c6a1af04543..053509d22aaff899c8b887e1cd75412f6a9bebce 100644
--- a/src/Analyzers/Analyzers/src/StartupAnalyzer.cs
+++ b/src/Analyzers/Analyzers/src/StartupAnalyzer.cs
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Immutable;
 using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Operations;
 
 namespace Microsoft.AspNetCore.Analyzers
 {
@@ -35,10 +36,12 @@ namespace Microsoft.AspNetCore.Analyzers
                 return;
             }
 
+            var entryPoint = context.Compilation.GetEntryPoint(context.CancellationToken);
+
             context.RegisterSymbolStartAction(context =>
             {
                 var type = (INamedTypeSymbol)context.Symbol;
-                if (!StartupFacts.IsStartupClass(symbols, type))
+                if (!StartupFacts.IsStartupClass(symbols, type) && !SymbolEqualityComparer.Default.Equals(entryPoint?.ContainingType, type))
                 {
                     // Not a startup class, nothing to do.
                     return;
@@ -60,18 +63,28 @@ namespace Microsoft.AspNetCore.Analyzers
                     }
 
                     var method = (IMethodSymbol)context.OwningSymbol;
-                    if (StartupFacts.IsConfigureServices(symbols, method))
+                    var isConfigureServices = StartupFacts.IsConfigureServices(symbols, method);
+                    if (isConfigureServices)
                     {
                         OnConfigureServicesMethodFound(method);
+                    }
 
+                    // In the future we can consider looking at more methods, but for now limit to Main, implicit Main, and Configure* methods
+                    var isMain = SymbolEqualityComparer.Default.Equals(entryPoint, context.OwningSymbol);
+
+                    if (isConfigureServices || isMain)
+                    {
                         services.AnalyzeConfigureServices(context);
                         options.AnalyzeConfigureServices(context);
                     }
 
-                    if (StartupFacts.IsConfigure(symbols, method))
+                    var isConfigure = StartupFacts.IsConfigure(symbols, method);
+                    if (isConfigure)
                     {
                         OnConfigureMethodFound(method);
-
+                    }
+                    if (isConfigure || isMain)
+                    {
                         middleware.AnalyzeConfigureMethod(context);
                     }
                 });
diff --git a/src/Analyzers/Analyzers/src/UseAuthorizationAnalyzer.cs b/src/Analyzers/Analyzers/src/UseAuthorizationAnalyzer.cs
index 57ef1050faa9694dff9a908c0d904aef05e6a431..72cc214e0958af8ff43eb5ade92eb91fe0e0fa0d 100644
--- a/src/Analyzers/Analyzers/src/UseAuthorizationAnalyzer.cs
+++ b/src/Analyzers/Analyzers/src/UseAuthorizationAnalyzer.cs
@@ -20,7 +20,6 @@ namespace Microsoft.AspNetCore.Analyzers
         public void AnalyzeSymbol(SymbolAnalysisContext context)
         {
             Debug.Assert(context.Symbol.Kind == SymbolKind.NamedType);
-            Debug.Assert(StartupFacts.IsStartupClass(_context.StartupSymbols, (INamedTypeSymbol)context.Symbol));
 
             var type = (INamedTypeSymbol)context.Symbol;
 
diff --git a/src/Analyzers/Analyzers/src/UseMvcAnalyzer.cs b/src/Analyzers/Analyzers/src/UseMvcAnalyzer.cs
index f4adf8a050cfd27b963b0a0cf45cf7d80a667291..02806e5228532c36c6d32f59c4fb0d3cd4719fa1 100644
--- a/src/Analyzers/Analyzers/src/UseMvcAnalyzer.cs
+++ b/src/Analyzers/Analyzers/src/UseMvcAnalyzer.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Diagnostics;
@@ -19,7 +19,6 @@ namespace Microsoft.AspNetCore.Analyzers
         public void AnalyzeSymbol(SymbolAnalysisContext context)
         {
             Debug.Assert(context.Symbol.Kind == SymbolKind.NamedType);
-            Debug.Assert(StartupFacts.IsStartupClass(_context.StartupSymbols, (INamedTypeSymbol)context.Symbol));
 
             var type = (INamedTypeSymbol)context.Symbol;
 
diff --git a/src/Analyzers/Analyzers/test/AnalyzersDiagnosticAnalyzerRunner.cs b/src/Analyzers/Analyzers/test/AnalyzersDiagnosticAnalyzerRunner.cs
index 7ec7449dbc8105c40fc9115baefdeb218a70c25d..1602bb8556afb5f2015cb7038d947f852b8b5e9a 100644
--- a/src/Analyzers/Analyzers/test/AnalyzersDiagnosticAnalyzerRunner.cs
+++ b/src/Analyzers/Analyzers/test/AnalyzersDiagnosticAnalyzerRunner.cs
@@ -14,9 +14,12 @@ namespace Microsoft.AspNetCore.Analyzers
 {
     internal class AnalyzersDiagnosticAnalyzerRunner : DiagnosticAnalyzerRunner
     {
-        public AnalyzersDiagnosticAnalyzerRunner(DiagnosticAnalyzer analyzer)
+        private readonly OutputKind _outputKind;
+
+        public AnalyzersDiagnosticAnalyzerRunner(DiagnosticAnalyzer analyzer, OutputKind? outputKind = null)
         {
             Analyzer = analyzer;
+            _outputKind = outputKind ?? OutputKind.DynamicallyLinkedLibrary;
         }
 
         public DiagnosticAnalyzer Analyzer { get; }
@@ -51,5 +54,10 @@ namespace Microsoft.AspNetCore.Analyzers
         {
             return GetDiagnosticsAsync(new[] { project }, Analyzer, Array.Empty<string>());
         }
+
+        protected override CompilationOptions ConfigureCompilationOptions(CompilationOptions options)
+        {
+            return options.WithOutputKind(_outputKind);
+        }
     }
 }
diff --git a/src/Analyzers/Analyzers/test/Microsoft.AspNetCore.Analyzers.Test.csproj b/src/Analyzers/Analyzers/test/Microsoft.AspNetCore.Analyzers.Test.csproj
index 8f85e4be8c9f06f72f0dc10f228abeae08e73c16..bab964826b35d3fdd4e18f6bec2dc509997d9dca 100644
--- a/src/Analyzers/Analyzers/test/Microsoft.AspNetCore.Analyzers.Test.csproj
+++ b/src/Analyzers/Analyzers/test/Microsoft.AspNetCore.Analyzers.Test.csproj
@@ -22,6 +22,7 @@
     <Reference Include="Microsoft.AspNetCore.Components.Server" />
     <Reference Include="Microsoft.AspNetCore.Mvc" />
     <Reference Include="Microsoft.AspNetCore.SignalR" />
+    <Reference Include="Microsoft.AspNetCore" />
   </ItemGroup>
 
 </Project>
diff --git a/src/Analyzers/Analyzers/test/MinimalStartupTest.cs b/src/Analyzers/Analyzers/test/MinimalStartupTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..5acd376109e506bd9620a9b5a2dd3e45437212cb
--- /dev/null
+++ b/src/Analyzers/Analyzers/test/MinimalStartupTest.cs
@@ -0,0 +1,363 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Analyzer.Testing;
+using Microsoft.CodeAnalysis;
+
+namespace Microsoft.AspNetCore.Analyzers
+{
+    public class MinimalStartupTest : StartupAnalyzerTestBase
+    {
+        public MinimalStartupTest()
+        {
+            Runner = new AnalyzersDiagnosticAnalyzerRunner(StartupAnalyzer, OutputKind.ConsoleApplication);
+        }
+
+        internal override bool HasConfigure => false;
+
+        internal override AnalyzersDiagnosticAnalyzerRunner Runner { get; }
+
+        [Fact]
+        public async Task StartupAnalyzer_AuthNoRouting()
+        {
+            // Arrange
+            var source = TestSource.Read(@"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.AspNetCore.Authorization;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddAuthorization();
+var app = builder.Build();
+app.UseAuthorization();
+app.Run();");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            Assert.Single(middlewareAnalysis.Middleware);
+            Assert.Empty(diagnostics);
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_WorksWithNonImplicitMain()
+        {
+            // Arrange
+            var source = TestSource.Read(@"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+public class Program
+{
+    public static void Main(string[] args)
+    {
+        var builder = WebApplication.CreateBuilder(args);
+        builder.Services.AddMvc();
+        var app = builder.Build();
+        app.UseStaticFiles();
+        app.UseMiddleware<AuthorizationMiddleware>();
+        /*MM*/app.UseMvc();
+        app.UseRouting();
+        app.UseEndpoints(endpoints =>
+        {
+        });
+        app.Run();
+    }
+}");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
+            Assert.False(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
+
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+
+            Assert.Collection(
+                middlewareAnalysis.Middleware,
+                item => Assert.Equal("UseStaticFiles", item.UseMethod.Name),
+                item => Assert.Equal("UseMiddleware", item.UseMethod.Name),
+                item => Assert.Equal("UseMvc", item.UseMethod.Name),
+                item => Assert.Equal("UseRouting", item.UseMethod.Name),
+                item => Assert.Equal("UseEndpoints", item.UseMethod.Name));
+
+            Assert.Collection(
+                diagnostics,
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
+                    Assert.Contains("inside 'Main", diagnostic.GetMessage());
+                });
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_WorksWithOtherMethodsInProgram()
+        {
+            // Arrange
+            var source = TestSource.Read(@"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+public class Program
+{
+    public static void Main(string[] args)
+    {
+        var builder = WebApplication.CreateBuilder(args);
+        builder.Services.AddMvc();
+        var app = builder.Build();
+        app.UseStaticFiles();
+        app.UseMiddleware<AuthorizationMiddleware>();
+        /*MM*/app.UseMvc();
+        app.UseRouting();
+        app.UseEndpoints(endpoints =>
+        {
+        });
+        app.Run();
+    }
+
+    private static void MethodA()
+    {
+    }
+
+    private static void MethodB()
+    {
+    }
+}");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
+            Assert.False(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
+
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+
+            Assert.Collection(
+                middlewareAnalysis.Middleware,
+                item => Assert.Equal("UseStaticFiles", item.UseMethod.Name),
+                item => Assert.Equal("UseMiddleware", item.UseMethod.Name),
+                item => Assert.Equal("UseMvc", item.UseMethod.Name),
+                item => Assert.Equal("UseRouting", item.UseMethod.Name),
+                item => Assert.Equal("UseEndpoints", item.UseMethod.Name));
+
+            Assert.Collection(
+                diagnostics,
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
+                    Assert.Contains("inside 'Main", diagnostic.GetMessage());
+                });
+        }
+
+        internal override TestSource GetSource(string scenario)
+        {
+            string source = null;
+            switch (scenario)
+            {
+                case "StartupSignatures_Standard": //passes
+                    source = @"using Microsoft.AspNetCore.Builder;
+var builder = WebApplication.CreateBuilder(args);
+var app = builder.Build();
+app.MapGet(""/"", () => ""Hello World!"");
+app.Run();";
+                    break;
+                case "StartupSignatures_MoreVariety": //passes
+                    source = @"using Microsoft.AspNetCore.Builder;
+var app = WebApplication.Create(args);
+app.MapGet(""/"", () => ""Hello World!"");
+app.Run();";
+                    break;
+                case "MvcOptions_UseMvcWithDefaultRouteAndEndpointRoutingDisabled": //passes
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddMvc(options => options.EnableEndpointRouting = false);
+var app = builder.Build();
+app.UseMvcWithDefaultRoute();
+app.Run();";
+                    break;
+                case "MvcOptions_UseMvcWithDefaultRouteAndAddMvcOptionsEndpointRoutingDisabled": //passes
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddMvc().AddMvcOptions(options => options.EnableEndpointRouting = false);
+var app = builder.Build();
+app.UseMvcWithDefaultRoute();
+app.Run();";
+                    break;
+                case "MvcOptions_UseMvc": //passes (fails)
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddMvc();
+var app = builder.Build();
+/*MM*/app.UseMvc();
+app.Run();";
+                    break;
+                case "MvcOptions_UseMvcAndConfiguredRoutes": //passes (fails)
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddMvc();
+var app = builder.Build();
+/*MM*/app.UseMvc(routes =>
+{
+    routes.MapRoute(""Name"", ""Template"");
+});
+app.Run();";
+                    break;
+                case "MvcOptions_UseMvcWithDefaultRoute": //passes (fails)
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddMvc();
+var app = builder.Build();
+/*MM*/app.UseMvcWithDefaultRoute();
+app.Run();";
+                    break;
+                case "MvcOptions_UseMvcWithOtherMiddleware": //passes (fails)
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.AspNetCore.Authorization;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddMvc();
+var app = builder.Build();
+app.UseStaticFiles();
+app.UseMiddleware<AuthorizationMiddleware>();
+/*MM*/app.UseMvc();
+app.UseRouting();
+app.UseEndpoints(endpoints =>
+{
+});
+app.Run();";
+                    break;
+                case "MvcOptions_UseMvcMultiple": //passes (fails)
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.AspNetCore.Authorization;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddMvc();
+var app = builder.Build();
+/*MM1*/app.UseMvcWithDefaultRoute();
+app.UseStaticFiles();
+app.UseMiddleware<AuthorizationMiddleware>();
+/*MM2*/app.UseMvc();
+app.UseRouting();
+app.UseEndpoints(endpoints =>
+{
+});
+/*MM3*/app.UseMvc();
+app.Run();";
+                    break;
+                case "UseAuthConfiguredCorrectly": //passes
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.AspNetCore.Authorization;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddAuthorization();
+var app = builder.Build();
+app.UseRouting();
+app.UseAuthorization();
+app.UseEndpoints(r => {});
+app.Run();";
+                    break;
+                case "UseAuthConfiguredCorrectlyChained": //passes
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddAuthorization();
+var app = builder.Build();
+app.UseRouting()
+    .UseAuthorization()
+    .UseEndpoints(r => {});
+app.Run();";
+                    break;
+                case "UseAuthMultipleTimes": //passes
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddAuthorization();
+var app = builder.Build();
+app.UseRouting();
+app.UseAuthorization();
+app.UseAuthorization();
+app.UseEndpoints(r => {});
+app.Run();";
+                    break;
+                case "UseAuthBeforeUseRouting": //passes (fails)
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddAuthorization();
+var app = builder.Build();
+app.UseFileServer();
+/*MM*/app.UseAuthorization();
+app.UseRouting();
+app.UseEndpoints(r => {});
+app.Run();";
+                    break;
+                case "UseAuthBeforeUseRoutingChained": //passes (fails)
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddAuthorization();
+var app = builder.Build();
+app.UseFileServer()
+    .UseAuthorization()
+    .UseRouting()
+    .UseEndpoints(r => {});
+app.Run();";
+                    break;
+                case "UseAuthAfterUseEndpoints": //passes (fails)
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddAuthorization();
+var app = builder.Build();
+app.UseRouting();
+app.UseEndpoints(r => { });
+/*MM*/app.UseAuthorization();
+app.Run();";
+                    break;
+                case "UseAuthFallbackPolicy": //passes
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddAuthorization();
+var app = builder.Build();
+app.UseAuthorization();
+app.UseStaticFiles();
+app.UseRouting();
+app.UseAuthorization();
+app.UseEndpoints(r => { });
+app.Run();";
+                    break;
+                case "ConfigureServices_BuildServiceProvider":
+                    source = @"using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+var builder = WebApplication.CreateBuilder(args);
+/*MM1*/builder.Services.BuildServiceProvider();
+var app = builder.Build();
+app.Run();";
+                    break;
+            }
+
+            return source is not null ? TestSource.Read(source) : null;
+        }
+    }
+}
diff --git a/src/Analyzers/Analyzers/test/StartupAnalyzerTest.cs b/src/Analyzers/Analyzers/test/StartupAnalyzerTest.cs
index bfbd89f1c9d939b332ad9afb7f7d522af866d09b..b0af27ceb84a6f709b1cee0907a35009c05e927e 100644
--- a/src/Analyzers/Analyzers/test/StartupAnalyzerTest.cs
+++ b/src/Analyzers/Analyzers/test/StartupAnalyzerTest.cs
@@ -1,350 +1,24 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Collections.Concurrent;
-using System.Linq;
-using System.Threading.Tasks;
 using Microsoft.AspNetCore.Analyzer.Testing;
-using Microsoft.CodeAnalysis;
-using Xunit;
 
 namespace Microsoft.AspNetCore.Analyzers
 {
-    public class StartupAnalyzerTest : AnalyzerTestBase
+    public class StartupAnalyzerTest : StartupAnalyzerTestBase
     {
         public StartupAnalyzerTest()
         {
-            StartupAnalyzer = new StartupAnalyzer();
-
             Runner = new AnalyzersDiagnosticAnalyzerRunner(StartupAnalyzer);
-
-            Analyses = new ConcurrentBag<object>();
-            ConfigureServicesMethods = new ConcurrentBag<IMethodSymbol>();
-            ConfigureMethods = new ConcurrentBag<IMethodSymbol>();
-            StartupAnalyzer.ServicesAnalysisCompleted += (sender, analysis) => Analyses.Add(analysis);
-            StartupAnalyzer.OptionsAnalysisCompleted += (sender, analysis) => Analyses.Add(analysis);
-            StartupAnalyzer.MiddlewareAnalysisCompleted += (sender, analysis) => Analyses.Add(analysis);
-            StartupAnalyzer.ConfigureServicesMethodFound += (sender, method) => ConfigureServicesMethods.Add(method);
-            StartupAnalyzer.ConfigureMethodFound += (sender, method) => ConfigureMethods.Add(method);
-        }
-
-        private StartupAnalyzer StartupAnalyzer { get; }
-
-        private AnalyzersDiagnosticAnalyzerRunner Runner { get; }
-
-        private ConcurrentBag<object> Analyses { get; }
-
-        private ConcurrentBag<IMethodSymbol> ConfigureServicesMethods { get; }
-
-        private ConcurrentBag<IMethodSymbol> ConfigureMethods { get; }
-
-        [Fact]
-        public async Task StartupAnalyzer_FindsStartupMethods_StartupSignatures_Standard()
-        {
-            // Arrange
-            var source = Read("StartupSignatures_Standard");
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            Assert.Empty(diagnostics);
-
-            Assert.Collection(ConfigureServicesMethods, m => Assert.Equal("ConfigureServices", m.Name));
-            Assert.Collection(ConfigureMethods, m => Assert.Equal("Configure", m.Name));
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_FindsStartupMethods_StartupSignatures_MoreVariety()
-        {
-            // Arrange
-            var source = Read("StartupSignatures_MoreVariety");
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            Assert.Empty(diagnostics);
-
-            Assert.Collection(
-                ConfigureServicesMethods.OrderBy(m => m.Name),
-                m => Assert.Equal("ConfigureServices", m.Name));
-
-            Assert.Collection(
-                ConfigureMethods.OrderBy(m => m.Name),
-                m => Assert.Equal("Configure", m.Name),
-                m => Assert.Equal("ConfigureProduction", m.Name));
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_MvcOptionsAnalysis_UseMvc_FindsEndpointRoutingDisabled()
-        {
-            // Arrange
-            var source = Read("MvcOptions_UseMvcWithDefaultRouteAndEndpointRoutingDisabled");
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
-            Assert.True(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
-
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            var middleware = Assert.Single(middlewareAnalysis.Middleware);
-            Assert.Equal("UseMvcWithDefaultRoute", middleware.UseMethod.Name);
-
-            Assert.Empty(diagnostics);
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_MvcOptionsAnalysis_AddMvcOptions_FindsEndpointRoutingDisabled()
-        {
-            // Arrange
-            var source = Read("MvcOptions_UseMvcWithDefaultRouteAndAddMvcOptionsEndpointRoutingDisabled");
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
-            Assert.True(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
-
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            var middleware = Assert.Single(middlewareAnalysis.Middleware);
-            Assert.Equal("UseMvcWithDefaultRoute", middleware.UseMethod.Name);
-
-            Assert.Empty(diagnostics);
-        }
-
-        [Theory]
-        [InlineData("MvcOptions_UseMvc", "UseMvc")]
-        [InlineData("MvcOptions_UseMvcAndConfiguredRoutes", "UseMvc")]
-        [InlineData("MvcOptions_UseMvcWithDefaultRoute", "UseMvcWithDefaultRoute")]
-        public async Task StartupAnalyzer_MvcOptionsAnalysis_FindsEndpointRoutingEnabled(string sourceFileName, string mvcMiddlewareName)
-        {
-            // Arrange
-            var source = Read(sourceFileName);
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
-            Assert.False(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
-
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            var middleware = Assert.Single(middlewareAnalysis.Middleware);
-            Assert.Equal(mvcMiddlewareName, middleware.UseMethod.Name);
-
-            Assert.Collection(
-                diagnostics,
-                diagnostic =>
-                {
-                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
-                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
-                });
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_MvcOptionsAnalysis_MultipleMiddleware()
-        {
-            // Arrange
-            var source = Read("MvcOptions_UseMvcWithOtherMiddleware");
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
-            Assert.False(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
-
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-
-            Assert.Collection(
-                middlewareAnalysis.Middleware,
-                item => Assert.Equal("UseStaticFiles", item.UseMethod.Name),
-                item => Assert.Equal("UseMiddleware", item.UseMethod.Name),
-                item => Assert.Equal("UseMvc", item.UseMethod.Name),
-                item => Assert.Equal("UseRouting", item.UseMethod.Name),
-                item => Assert.Equal("UseEndpoints", item.UseMethod.Name));
-
-            Assert.Collection(
-                diagnostics,
-                diagnostic =>
-                {
-                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
-                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
-                });
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_MvcOptionsAnalysis_MultipleUseMvc()
-        {
-            // Arrange
-            var source = Read("MvcOptions_UseMvcMultiple");
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
-            Assert.False(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
-
-            Assert.Collection(
-                diagnostics,
-                diagnostic =>
-                {
-                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
-                    AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM1"], diagnostic.Location);
-                },
-                diagnostic =>
-                {
-                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
-                    AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM2"], diagnostic.Location);
-                },
-                diagnostic =>
-                {
-                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
-                    AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM3"], diagnostic.Location);
-                });
         }
 
-        [Fact]
-        public async Task StartupAnalyzer_ServicesAnalysis_CallBuildServiceProvider()
-        {
-            // Arrange
-            var source = Read("ConfigureServices_BuildServiceProvider");
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+        internal override bool HasConfigure => true;
 
-            // Assert
-            var servicesAnalysis = Assert.Single(Analyses.OfType<ServicesAnalysis>());
-            Assert.NotEmpty(servicesAnalysis.Services);
-            Assert.Collection(diagnostics,
-                diagnostic =>
-                {
-                    Assert.Same(StartupAnalyzer.Diagnostics.BuildServiceProviderShouldNotCalledInConfigureServicesMethod, diagnostic.Descriptor);
-                    AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM1"], diagnostic.Location);
-                });
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_UseAuthorizationConfiguredCorrectly_ReportsNoDiagnostics()
-        {
-            // Arrange
-            var source = Read(nameof(TestFiles.StartupAnalyzerTest.UseAuthConfiguredCorrectly));
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            Assert.NotEmpty(middlewareAnalysis.Middleware);
-            Assert.Empty(diagnostics);
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_UseAuthorizationConfiguredAsAChain_ReportsNoDiagnostics()
-        {
-            // Regression test for https://github.com/dotnet/aspnetcore/issues/15203
-            // Arrange
-            var source = Read(nameof(TestFiles.StartupAnalyzerTest.UseAuthConfiguredCorrectlyChained));
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            Assert.NotEmpty(middlewareAnalysis.Middleware);
-            Assert.Empty(diagnostics);
-        }
+        internal override AnalyzersDiagnosticAnalyzerRunner Runner { get; }
 
-        [Fact]
-        public async Task StartupAnalyzer_UseAuthorizationInvokedMultipleTimesInEndpointRoutingBlock_ReportsNoDiagnostics()
+        internal override TestSource GetSource(string scenario)
         {
-            // Arrange
-            var source = Read(nameof(TestFiles.StartupAnalyzerTest.UseAuthMultipleTimes));
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            Assert.NotEmpty(middlewareAnalysis.Middleware);
-            Assert.Empty(diagnostics);
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_UseAuthorizationConfiguredBeforeUseRouting_ReportsDiagnostics()
-        {
-            // Arrange
-            var source = Read(nameof(TestFiles.StartupAnalyzerTest.UseAuthBeforeUseRouting));
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            Assert.NotEmpty(middlewareAnalysis.Middleware);
-            Assert.Collection(diagnostics,
-                diagnostic =>
-                {
-                    Assert.Same(StartupAnalyzer.Diagnostics.IncorrectlyConfiguredAuthorizationMiddleware, diagnostic.Descriptor);
-                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
-                });
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_UseAuthorizationConfiguredBeforeUseRoutingChained_ReportsDiagnostics()
-        {
-            // This one asserts a false negative for https://github.com/dotnet/aspnetcore/issues/15203.
-            // We don't correctly identify chained calls, this test verifies the behavior.
-            // Arrange
-            var source = Read(nameof(TestFiles.StartupAnalyzerTest.UseAuthBeforeUseRoutingChained));
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            Assert.NotEmpty(middlewareAnalysis.Middleware);
-            Assert.Empty(diagnostics);
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_UseAuthorizationConfiguredAfterUseEndpoints_ReportsDiagnostics()
-        {
-            // Arrange
-            var source = Read(nameof(TestFiles.StartupAnalyzerTest.UseAuthAfterUseEndpoints));
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            Assert.NotEmpty(middlewareAnalysis.Middleware);
-            Assert.Collection(diagnostics,
-                diagnostic =>
-                {
-                    Assert.Same(StartupAnalyzer.Diagnostics.IncorrectlyConfiguredAuthorizationMiddleware, diagnostic.Descriptor);
-                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
-                });
-        }
-
-        [Fact]
-        public async Task StartupAnalyzer_MultipleUseAuthorization_ReportsNoDiagnostics()
-        {
-            // Arrange
-            var source = Read(nameof(TestFiles.StartupAnalyzerTest.UseAuthFallbackPolicy));
-
-            // Act
-            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
-
-            // Assert
-            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
-            Assert.NotEmpty(middlewareAnalysis.Middleware);
-            Assert.Empty(diagnostics);
+            return Read(scenario);
         }
     }
 }
diff --git a/src/Analyzers/Analyzers/test/StartupAnalyzerTestBase.cs b/src/Analyzers/Analyzers/test/StartupAnalyzerTestBase.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f84a7483dfbf041fd57d4d61164ed981af5edaf6
--- /dev/null
+++ b/src/Analyzers/Analyzers/test/StartupAnalyzerTestBase.cs
@@ -0,0 +1,355 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Concurrent;
+using Microsoft.AspNetCore.Analyzer.Testing;
+using Microsoft.CodeAnalysis;
+
+namespace Microsoft.AspNetCore.Analyzers
+{
+    public abstract class StartupAnalyzerTestBase : AnalyzerTestBase
+    {
+        public StartupAnalyzerTestBase()
+        {
+            StartupAnalyzer = new StartupAnalyzer();
+
+            Analyses = new ConcurrentBag<object>();
+            ConfigureServicesMethods = new ConcurrentBag<IMethodSymbol>();
+            ConfigureMethods = new ConcurrentBag<IMethodSymbol>();
+            StartupAnalyzer.ServicesAnalysisCompleted += (sender, analysis) => Analyses.Add(analysis);
+            StartupAnalyzer.OptionsAnalysisCompleted += (sender, analysis) => Analyses.Add(analysis);
+            StartupAnalyzer.MiddlewareAnalysisCompleted += (sender, analysis) => Analyses.Add(analysis);
+            StartupAnalyzer.ConfigureServicesMethodFound += (sender, method) => ConfigureServicesMethods.Add(method);
+            StartupAnalyzer.ConfigureMethodFound += (sender, method) => ConfigureMethods.Add(method);
+        }
+
+        internal abstract bool HasConfigure { get; }
+
+        internal StartupAnalyzer StartupAnalyzer { get; }
+
+        internal abstract AnalyzersDiagnosticAnalyzerRunner Runner { get; }
+
+        internal ConcurrentBag<object> Analyses { get; }
+
+        internal ConcurrentBag<IMethodSymbol> ConfigureServicesMethods { get; }
+
+        internal ConcurrentBag<IMethodSymbol> ConfigureMethods { get; }
+
+        internal abstract TestSource GetSource(string scenario);
+
+        [Fact]
+        public async Task StartupAnalyzer_FindsStartupMethods_StartupSignatures_Standard()
+        {
+            // Arrange
+            var source = GetSource("StartupSignatures_Standard");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            Assert.Empty(diagnostics);
+
+            if (HasConfigure)
+            {
+                Assert.Collection(ConfigureServicesMethods, m => Assert.Equal("ConfigureServices", m.Name));
+                Assert.Collection(ConfigureMethods, m => Assert.Equal("Configure", m.Name));
+            }
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_FindsStartupMethods_StartupSignatures_MoreVariety()
+        {
+            // Arrange
+            var source = GetSource("StartupSignatures_MoreVariety");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            Assert.Empty(diagnostics);
+
+            if (HasConfigure)
+            {
+                Assert.Collection(
+                ConfigureServicesMethods.OrderBy(m => m.Name),
+                m => Assert.Equal("ConfigureServices", m.Name));
+
+                Assert.Collection(
+                    ConfigureMethods.OrderBy(m => m.Name),
+                    m => Assert.Equal("Configure", m.Name),
+                    m => Assert.Equal("ConfigureProduction", m.Name));
+            }
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_MvcOptionsAnalysis_UseMvc_FindsEndpointRoutingDisabled()
+        {
+            // Arrange
+            var source = GetSource("MvcOptions_UseMvcWithDefaultRouteAndEndpointRoutingDisabled");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
+            Assert.True(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
+
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            var middleware = Assert.Single(middlewareAnalysis.Middleware);
+            Assert.Equal("UseMvcWithDefaultRoute", middleware.UseMethod.Name);
+
+            Assert.Empty(diagnostics);
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_MvcOptionsAnalysis_AddMvcOptions_FindsEndpointRoutingDisabled()
+        {
+            // Arrange
+            var source = GetSource("MvcOptions_UseMvcWithDefaultRouteAndAddMvcOptionsEndpointRoutingDisabled");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
+            Assert.True(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
+
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            var middleware = Assert.Single(middlewareAnalysis.Middleware);
+            Assert.Equal("UseMvcWithDefaultRoute", middleware.UseMethod.Name);
+
+            Assert.Empty(diagnostics);
+        }
+
+        [Theory]
+        [InlineData("MvcOptions_UseMvc", "UseMvc")]
+        [InlineData("MvcOptions_UseMvcAndConfiguredRoutes", "UseMvc")]
+        [InlineData("MvcOptions_UseMvcWithDefaultRoute", "UseMvcWithDefaultRoute")]
+        public async Task StartupAnalyzer_MvcOptionsAnalysis_FindsEndpointRoutingEnabled(string sourceFileName, string mvcMiddlewareName)
+        {
+            // Arrange
+            var source = GetSource(sourceFileName);
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
+            Assert.False(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
+
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            var middleware = Assert.Single(middlewareAnalysis.Middleware);
+            Assert.Equal(mvcMiddlewareName, middleware.UseMethod.Name);
+
+            Assert.Collection(
+                diagnostics,
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
+                });
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_MvcOptionsAnalysis_MultipleMiddleware()
+        {
+            // Arrange
+            var source = GetSource("MvcOptions_UseMvcWithOtherMiddleware");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
+            Assert.False(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
+
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+
+            Assert.Collection(
+                middlewareAnalysis.Middleware,
+                item => Assert.Equal("UseStaticFiles", item.UseMethod.Name),
+                item => Assert.Equal("UseMiddleware", item.UseMethod.Name),
+                item => Assert.Equal("UseMvc", item.UseMethod.Name),
+                item => Assert.Equal("UseRouting", item.UseMethod.Name),
+                item => Assert.Equal("UseEndpoints", item.UseMethod.Name));
+
+            Assert.Collection(
+                diagnostics,
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
+                });
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_MvcOptionsAnalysis_MultipleUseMvc()
+        {
+            // Arrange
+            var source = GetSource("MvcOptions_UseMvcMultiple");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var optionsAnalysis = Assert.Single(Analyses.OfType<OptionsAnalysis>());
+            Assert.False(OptionsFacts.IsEndpointRoutingExplicitlyDisabled(optionsAnalysis));
+
+            Assert.Collection(
+                diagnostics,
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM1"], diagnostic.Location);
+                },
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM2"], diagnostic.Location);
+                },
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.UnsupportedUseMvcWithEndpointRouting, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM3"], diagnostic.Location);
+                });
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_ServicesAnalysis_CallBuildServiceProvider()
+        {
+            // Arrange
+            var source = GetSource("ConfigureServices_BuildServiceProvider");
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var servicesAnalysis = Assert.Single(Analyses.OfType<ServicesAnalysis>());
+            Assert.NotEmpty(servicesAnalysis.Services);
+            Assert.Collection(diagnostics,
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.BuildServiceProviderShouldNotCalledInConfigureServicesMethod, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MM1"], diagnostic.Location);
+                });
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_UseAuthorizationConfiguredCorrectly_ReportsNoDiagnostics()
+        {
+            // Arrange
+            var source = GetSource(nameof(TestFiles.StartupAnalyzerTest.UseAuthConfiguredCorrectly));
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            Assert.NotEmpty(middlewareAnalysis.Middleware);
+            Assert.Empty(diagnostics);
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_UseAuthorizationConfiguredAsAChain_ReportsNoDiagnostics()
+        {
+            // Regression test for https://github.com/dotnet/aspnetcore/issues/15203
+            // Arrange
+            var source = GetSource(nameof(TestFiles.StartupAnalyzerTest.UseAuthConfiguredCorrectlyChained));
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            Assert.NotEmpty(middlewareAnalysis.Middleware);
+            Assert.Empty(diagnostics);
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_UseAuthorizationInvokedMultipleTimesInEndpointRoutingBlock_ReportsNoDiagnostics()
+        {
+            // Arrange
+            var source = GetSource(nameof(TestFiles.StartupAnalyzerTest.UseAuthMultipleTimes));
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            Assert.NotEmpty(middlewareAnalysis.Middleware);
+            Assert.Empty(diagnostics);
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_UseAuthorizationConfiguredBeforeUseRouting_ReportsDiagnostics()
+        {
+            // Arrange
+            var source = GetSource(nameof(TestFiles.StartupAnalyzerTest.UseAuthBeforeUseRouting));
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            Assert.NotEmpty(middlewareAnalysis.Middleware);
+            Assert.Collection(diagnostics,
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.IncorrectlyConfiguredAuthorizationMiddleware, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
+                });
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_UseAuthorizationConfiguredBeforeUseRoutingChained_ReportsDiagnostics()
+        {
+            // This one asserts a false negative for https://github.com/dotnet/aspnetcore/issues/15203.
+            // We don't correctly identify chained calls, this test verifies the behavior.
+            // Arrange
+            var source = GetSource(nameof(TestFiles.StartupAnalyzerTest.UseAuthBeforeUseRoutingChained));
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            Assert.NotEmpty(middlewareAnalysis.Middleware);
+            Assert.Empty(diagnostics);
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_UseAuthorizationConfiguredAfterUseEndpoints_ReportsDiagnostics()
+        {
+            // Arrange
+            var source = GetSource(nameof(TestFiles.StartupAnalyzerTest.UseAuthAfterUseEndpoints));
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            Assert.NotEmpty(middlewareAnalysis.Middleware);
+            Assert.Collection(diagnostics,
+                diagnostic =>
+                {
+                    Assert.Same(StartupAnalyzer.Diagnostics.IncorrectlyConfiguredAuthorizationMiddleware, diagnostic.Descriptor);
+                    AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location);
+                });
+        }
+
+        [Fact]
+        public async Task StartupAnalyzer_MultipleUseAuthorization_ReportsNoDiagnostics()
+        {
+            // Arrange
+            var source = GetSource(nameof(TestFiles.StartupAnalyzerTest.UseAuthFallbackPolicy));
+
+            // Act
+            var diagnostics = await Runner.GetDiagnosticsAsync(source.Source);
+
+            // Assert
+            var middlewareAnalysis = Assert.Single(Analyses.OfType<MiddlewareAnalysis>());
+            Assert.NotEmpty(middlewareAnalysis.Middleware);
+            Assert.Empty(diagnostics);
+        }
+    }
+}