Add nullable annotations to M.A.Hosting and DefaultBuilder (#24571)

* Turn on nullability annotations for public types in M.A.Hosting
* Turn on nullability annotations for Microsoft.AspNetCore and
  Microsoft.AspNetCore.Server.Abstractions

Contributes to https://github.com/dotnet/aspnetcore/issues/5680
This commit is contained in:
Pranav K 2020-08-04 18:07:11 -07:00 committed by GitHub
parent e2d2aaa753
commit bb9653532a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 62 additions and 35 deletions

View File

@ -25,6 +25,11 @@ namespace Microsoft.Extensions.Hosting
/// <returns>The <see cref="IHostBuilder"/> for chaining.</returns>
public static IHostBuilder ConfigureWebHostDefaults(this IHostBuilder builder, Action<IWebHostBuilder> configure)
{
if (configure is null)
{
throw new ArgumentNullException(nameof(configure));
}
return builder.ConfigureWebHost(webHostBuilder =>
{
WebHost.ConfigureWebDefaults(webHostBuilder);

View File

@ -7,6 +7,7 @@
<Description>Microsoft.AspNetCore</Description>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>

View File

@ -40,9 +40,9 @@ namespace Microsoft.AspNetCore
/// <param name="url">The URL the hosted application will listen on.</param>
/// <param name="app">A delegate that handles requests to the application.</param>
/// <returns>A started <see cref="IWebHost"/> that hosts the application.</returns>
public static IWebHost Start(string url, RequestDelegate app)
public static IWebHost Start(string? url, RequestDelegate app)
{
var startupAssemblyName = app.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name;
var startupAssemblyName = app.GetMethodInfo().DeclaringType!.GetTypeInfo().Assembly.GetName().Name;
return StartWith(url: url, configureServices: null, app: appBuilder => appBuilder.Run(app), applicationName: startupAssemblyName);
}
@ -62,9 +62,9 @@ namespace Microsoft.AspNetCore
/// <param name="url">The URL the hosted application will listen on.</param>
/// <param name="routeBuilder">A delegate that configures the router for handling requests to the application.</param>
/// <returns>A started <see cref="IWebHost"/> that hosts the application.</returns>
public static IWebHost Start(string url, Action<IRouteBuilder> routeBuilder)
public static IWebHost Start(string? url, Action<IRouteBuilder> routeBuilder)
{
var startupAssemblyName = routeBuilder.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name;
var startupAssemblyName = routeBuilder.GetMethodInfo().DeclaringType!.GetTypeInfo().Assembly.GetName().Name;
return StartWith(url, services => services.AddRouting(), appBuilder => appBuilder.UseRouter(routeBuilder), applicationName: startupAssemblyName);
}
@ -84,10 +84,10 @@ namespace Microsoft.AspNetCore
/// <param name="url">The URL the hosted application will listen on.</param>
/// <param name="app">The delegate that configures the <see cref="IApplicationBuilder"/>.</param>
/// <returns>A started <see cref="IWebHost"/> that hosts the application.</returns>
public static IWebHost StartWith(string url, Action<IApplicationBuilder> app) =>
public static IWebHost StartWith(string? url, Action<IApplicationBuilder> app) =>
StartWith(url: url, configureServices: null, app: app, applicationName: null);
private static IWebHost StartWith(string url, Action<IServiceCollection> configureServices, Action<IApplicationBuilder> app, string applicationName)
private static IWebHost StartWith(string? url, Action<IServiceCollection>? configureServices, Action<IApplicationBuilder> app, string? applicationName)
{
var builder = CreateDefaultBuilder();
@ -153,7 +153,7 @@ namespace Microsoft.AspNetCore
/// </remarks>
/// <param name="args">The command line args.</param>
/// <returns>The initialized <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
public static IWebHostBuilder CreateDefaultBuilder(string[]? args)
{
var builder = new WebHostBuilder();

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Features;

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
@ -12,7 +14,7 @@ namespace Microsoft.AspNetCore.Http
{
public class DefaultHttpContextFactory : IHttpContextFactory
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IHttpContextAccessor? _httpContextAccessor;
private readonly FormOptions _formOptions;
private readonly IServiceScopeFactory _serviceScopeFactory;
@ -26,7 +28,7 @@ namespace Microsoft.AspNetCore.Http
_serviceScopeFactory = serviceProvider.GetRequiredService<IServiceScopeFactory>();
}
internal IHttpContextAccessor HttpContextAccessor => _httpContextAccessor;
internal IHttpContextAccessor? HttpContextAccessor => _httpContextAccessor;
public HttpContext Create(IFeatureCollection featureCollection)
{

View File

@ -8,6 +8,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;hosting</PackageTags>
<IsPackable>false</IsPackable>
<LangVersion>9.0</LangVersion>
</PropertyGroup>
<ItemGroup>

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System.Collections.Generic;
namespace Microsoft.AspNetCore.Hosting.Server.Features

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
@ -18,4 +20,4 @@ namespace Microsoft.AspNetCore.Hosting
public override void Configure(IApplicationBuilder app) => _configureApp(app);
}
}
}

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

View File

@ -1,9 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
@ -24,13 +27,13 @@ namespace Microsoft.AspNetCore.Hosting
public class WebHostBuilder : IWebHostBuilder
{
private readonly HostingEnvironment _hostingEnvironment;
private Action<WebHostBuilderContext, IServiceCollection> _configureServices;
private readonly IConfiguration _config;
private readonly WebHostBuilderContext _context;
private IConfiguration _config;
private WebHostOptions _options;
private WebHostBuilderContext _context;
private WebHostOptions? _options;
private bool _webHostBuilt;
private Action<WebHostBuilderContext, IConfigurationBuilder> _configureAppConfigurationBuilder;
private Action<WebHostBuilderContext, IServiceCollection>? _configureServices;
private Action<WebHostBuilderContext, IConfigurationBuilder>? _configureAppConfigurationBuilder;
/// <summary>
/// Initializes a new instance of the <see cref="WebHostBuilder"/> class.
@ -78,7 +81,7 @@ namespace Microsoft.AspNetCore.Hosting
/// <param name="key">The key of the setting to add or replace.</param>
/// <param name="value">The value of the setting to add or replace.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public IWebHostBuilder UseSetting(string key, string value)
public IWebHostBuilder UseSetting(string key, string? value)
{
_config[key] = value;
return this;
@ -212,7 +215,8 @@ namespace Microsoft.AspNetCore.Hosting
}
}
private IServiceCollection BuildCommonServices(out AggregateException hostingStartupErrors)
[MemberNotNull(nameof(_options))]
private IServiceCollection BuildCommonServices(out AggregateException? hostingStartupErrors)
{
hostingStartupErrors = null;
@ -231,7 +235,7 @@ namespace Microsoft.AspNetCore.Hosting
foreach (var attribute in assembly.GetCustomAttributes<HostingStartupAttribute>())
{
var hostingStartup = (IHostingStartup)Activator.CreateInstance(attribute.HostingStartupType);
var hostingStartup = (IHostingStartup)Activator.CreateInstance(attribute.HostingStartupType)!;
hostingStartup.Configure(this);
}
}
@ -330,8 +334,8 @@ namespace Microsoft.AspNetCore.Hosting
// NOTE: This code overrides original services lifetime. Instances would always be singleton in
// application container.
var listener = hostingServiceProvider.GetService<DiagnosticListener>();
services.Replace(ServiceDescriptor.Singleton(typeof(DiagnosticListener), listener));
services.Replace(ServiceDescriptor.Singleton(typeof(DiagnosticSource), listener));
services.Replace(ServiceDescriptor.Singleton(typeof(DiagnosticListener), listener!));
services.Replace(ServiceDescriptor.Singleton(typeof(DiagnosticSource), listener!));
}
private string ResolveContentRootPath(string contentRootPath, string basePath)

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
@ -25,7 +27,7 @@ namespace Microsoft.AspNetCore.Hosting
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder Configure(this IWebHostBuilder hostBuilder, Action<IApplicationBuilder> configureApp)
{
return hostBuilder.Configure((_, app) => configureApp(app), configureApp.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name);
return hostBuilder.Configure((_, app) => configureApp(app), configureApp.GetMethodInfo().DeclaringType!.GetTypeInfo().Assembly.GetName().Name!);
}
/// <summary>
@ -36,7 +38,7 @@ namespace Microsoft.AspNetCore.Hosting
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public static IWebHostBuilder Configure(this IWebHostBuilder hostBuilder, Action<WebHostBuilderContext, IApplicationBuilder> configureApp)
{
return hostBuilder.Configure(configureApp, configureApp.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name);
return hostBuilder.Configure(configureApp, configureApp.GetMethodInfo().DeclaringType!.GetTypeInfo().Assembly.GetName().Name!);
}
private static IWebHostBuilder Configure(this IWebHostBuilder hostBuilder, Action<WebHostBuilderContext, IApplicationBuilder> configureApp, string startupAssemblyName)
@ -77,7 +79,7 @@ namespace Microsoft.AspNetCore.Hosting
throw new ArgumentNullException(nameof(startupFactory));
}
var startupAssemblyName = startupFactory.GetMethodInfo().DeclaringType.GetTypeInfo().Assembly.GetName().Name;
var startupAssemblyName = startupFactory.GetMethodInfo().DeclaringType!.GetTypeInfo().Assembly.GetName().Name;
hostBuilder.UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName);

View File

@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using System.Threading;
using System.Threading.Tasks;
@ -103,7 +105,7 @@ namespace Microsoft.AspNetCore.Hosting
}
}
private static async Task RunAsync(this IWebHost host, CancellationToken token, string startupMessage)
private static async Task RunAsync(this IWebHost host, CancellationToken token, string? startupMessage)
{
try
{
@ -114,8 +116,8 @@ namespace Microsoft.AspNetCore.Hosting
if (!options.SuppressStatusMessages)
{
Console.WriteLine($"Hosting environment: {hostingEnvironment.EnvironmentName}");
Console.WriteLine($"Content root path: {hostingEnvironment.ContentRootPath}");
Console.WriteLine($"Hosting environment: {hostingEnvironment?.EnvironmentName}");
Console.WriteLine($"Content root path: {hostingEnvironment?.ContentRootPath}");
var serverAddresses = host.ServerFeatures.Get<IServerAddressesFeature>()?.Addresses;
@ -150,18 +152,18 @@ namespace Microsoft.AspNetCore.Hosting
private static async Task WaitForTokenShutdownAsync(this IWebHost host, CancellationToken token)
{
var applicationLifetime = host.Services.GetService<IHostApplicationLifetime>();
var applicationLifetime = host.Services.GetRequiredService<IHostApplicationLifetime>();
token.Register(state =>
{
((IHostApplicationLifetime)state).StopApplication();
((IHostApplicationLifetime)state!).StopApplication();
},
applicationLifetime);
var waitForStop = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
applicationLifetime.ApplicationStopping.Register(obj =>
{
var tcs = (TaskCompletionSource)obj;
var tcs = (TaskCompletionSource)obj!;
tcs.TrySetResult();
}, waitForStop);

View File

@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Hosting.Server.Abstractions
/// its <typeparamref name="TContext"/> between requests.
/// </summary>
/// <typeparam name="TContext">The <see cref="IHttpApplication{TContext}"/> Host context</typeparam>
public interface IHostContextContainer<TContext>
public interface IHostContextContainer<TContext> where TContext : notnull
{
TContext HostContext { get; set; }
}

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Hosting.Server
/// Represents an application.
/// </summary>
/// <typeparam name="TContext">The context associated with the application.</typeparam>
public interface IHttpApplication<TContext>
public interface IHttpApplication<TContext> where TContext : notnull
{
/// <summary>
/// Create a TContext given a collection of HTTP features.

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Hosting.Server
/// <param name="application">An instance of <see cref="IHttpApplication{TContext}"/>.</param>
/// <typeparam name="TContext">The context associated with the application.</typeparam>
/// <param name="cancellationToken">Indicates if the server startup should be aborted.</param>
Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken);
Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken) where TContext : notnull;
/// <summary>
/// Stop processing requests and shut down the server, gracefully if possible.

View File

@ -16,6 +16,6 @@ namespace Microsoft.AspNetCore.Hosting.Server
/// <summary>
/// The name of the authentication scheme for the server authentication handler.
/// </summary>
string AuthenticationScheme { get; }
string? AuthenticationScheme { get; }
}
}

View File

@ -8,6 +8,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;hosting</PackageTags>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>

View File

@ -16,6 +16,6 @@ namespace Microsoft.AspNetCore.Hosting.Server
/// <summary>
/// The name of the authentication scheme for the server authentication handler.
/// </summary>
public string AuthenticationScheme { get; set; }
public string? AuthenticationScheme { get; set; }
}
}

3
src/Hosting/build.cmd Normal file
View File

@ -0,0 +1,3 @@
@ECHO OFF
SET RepoRoot=%~dp0..\..
%RepoRoot%\build.cmd -projects %~dp0**\*.*proj %*