Fix some linker warnings, report others (#24553)

* Fix some linker warnings, report others
- Added RequiresUnreferencedCode to UseStartup that takes a string
- Added some suppressions
- Fixed ConfigureContainer calls
- Fixed HostingStartupAttribute
This commit is contained in:
David Fowler 2020-08-04 12:40:42 -07:00 committed by GitHub
parent e13368391b
commit cfd20ad2d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 22 additions and 10 deletions

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@ -47,6 +48,7 @@ namespace Microsoft.AspNetCore.Hosting
/// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param> /// <param name="hostBuilder">The <see cref="IWebHostBuilder"/> to configure.</param>
/// <param name="startupAssemblyName">The name of the assembly containing the startup type.</param> /// <param name="startupAssemblyName">The name of the assembly containing the startup type.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns> /// <returns>The <see cref="IWebHostBuilder"/>.</returns>
[RequiresUnreferencedCode("Types and members the loaded assembly depends on might be removed.")]
public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, string startupAssemblyName) public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, string startupAssemblyName)
{ {
if (startupAssemblyName == null) if (startupAssemblyName == null)
@ -54,7 +56,6 @@ namespace Microsoft.AspNetCore.Hosting
throw new ArgumentNullException(nameof(startupAssemblyName)); throw new ArgumentNullException(nameof(startupAssemblyName));
} }
return hostBuilder return hostBuilder
.UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName) .UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName)
.UseSetting(WebHostDefaults.StartupAssemblyKey, startupAssemblyName); .UseSetting(WebHostDefaults.StartupAssemblyKey, startupAssemblyName);

View File

@ -1,7 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
namespace Microsoft.AspNetCore.Hosting namespace Microsoft.AspNetCore.Hosting
@ -16,7 +17,7 @@ namespace Microsoft.AspNetCore.Hosting
/// Constructs the <see cref="HostingStartupAttribute"/> with the specified type. /// Constructs the <see cref="HostingStartupAttribute"/> with the specified type.
/// </summary> /// </summary>
/// <param name="hostingStartupType">A type that implements <see cref="IHostingStartup"/>.</param> /// <param name="hostingStartupType">A type that implements <see cref="IHostingStartup"/>.</param>
public HostingStartupAttribute(Type hostingStartupType) public HostingStartupAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type hostingStartupType)
{ {
if (hostingStartupType == null) if (hostingStartupType == null)
{ {
@ -35,6 +36,7 @@ namespace Microsoft.AspNetCore.Hosting
/// The implementation of <see cref="IHostingStartup"/> that should be loaded when /// The implementation of <see cref="IHostingStartup"/> that should be loaded when
/// starting an application. /// starting an application.
/// </summary> /// </summary>
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
public Type HostingStartupType { get; } public Type HostingStartupType { get; }
} }
} }

View File

@ -234,6 +234,7 @@ namespace Microsoft.AspNetCore.Hosting
return this; return this;
} }
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", Justification = "We need to call a generic method on IHostBuilder.")]
private void UseStartup([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupType, HostBuilderContext context, IServiceCollection services, object instance = null) private void UseStartup([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupType, HostBuilderContext context, IServiceCollection services, object instance = null)
{ {
var webHostBuilderContext = GetWebHostBuilderContext(context); var webHostBuilderContext = GetWebHostBuilderContext(context);
@ -275,12 +276,12 @@ namespace Microsoft.AspNetCore.Hosting
var actionType = typeof(Action<,>).MakeGenericType(typeof(HostBuilderContext), containerType); var actionType = typeof(Action<,>).MakeGenericType(typeof(HostBuilderContext), containerType);
// Get the private ConfigureContainer method on this type then close over the container type // Get the private ConfigureContainer method on this type then close over the container type
var configureCallback = GetType().GetMethod(nameof(ConfigureContainer), BindingFlags.NonPublic | BindingFlags.Instance) var configureCallback = typeof(GenericWebHostBuilder).GetMethod(nameof(ConfigureContainerImpl), BindingFlags.NonPublic | BindingFlags.Instance)
.MakeGenericMethod(containerType) .MakeGenericMethod(containerType)
.CreateDelegate(actionType, this); .CreateDelegate(actionType, this);
// _builder.ConfigureContainer<T>(ConfigureContainer); // _builder.ConfigureContainer<T>(ConfigureContainer);
typeof(IHostBuilder).GetMethods().First(m => m.Name == nameof(IHostBuilder.ConfigureContainer)) typeof(IHostBuilder).GetMethod(nameof(IHostBuilder.ConfigureContainer))
.MakeGenericMethod(containerType) .MakeGenericMethod(containerType)
.InvokeWithoutWrappingExceptions(_builder, new object[] { configureCallback }); .InvokeWithoutWrappingExceptions(_builder, new object[] { configureCallback });
} }
@ -310,7 +311,7 @@ namespace Microsoft.AspNetCore.Hosting
}); });
} }
private void ConfigureContainer<TContainer>(HostBuilderContext context, TContainer container) private void ConfigureContainerImpl<TContainer>(HostBuilderContext context, TContainer container)
{ {
var instance = context.Properties[_startupKey]; var instance = context.Properties[_startupKey];
var builder = (ConfigureContainerBuilder)context.Properties[typeof(ConfigureContainerBuilder)]; var builder = (ConfigureContainerBuilder)context.Properties[typeof(ConfigureContainerBuilder)];

View File

@ -222,6 +222,7 @@ namespace Microsoft.AspNetCore.Hosting
} }
} }
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "We're warning at the entry point. This is an implementation detail.")]
public static Type FindStartupType(string startupAssemblyName, string environmentName) public static Type FindStartupType(string startupAssemblyName, string environmentName)
{ {
if (string.IsNullOrEmpty(startupAssemblyName)) if (string.IsNullOrEmpty(startupAssemblyName))

View File

@ -79,8 +79,9 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
// https://stackoverflow.com/a/37983587/102052 // https://stackoverflow.com/a/37983587/102052
// //
// 2. If "dotnet publish" does hang indefinitely for some reason, tests should fail fast with an error message. // 2. If "dotnet publish" does hang indefinitely for some reason, tests should fail fast with an error message.
const int timeoutMinutes = 5; var timeout = deploymentParameters.PublishTimeout ?? TimeSpan.FromMinutes(5);
if (hostProcess.WaitForExit(milliseconds: timeoutMinutes * 60 * 1000))
if (hostProcess.WaitForExit(milliseconds: (int)timeout.TotalMilliseconds))
{ {
if (hostProcess.ExitCode != 0) if (hostProcess.ExitCode != 0)
{ {
@ -91,7 +92,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
} }
else else
{ {
var message = $"{DotnetCommandName} publish failed to exit after {timeoutMinutes} minutes"; var message = $"{DotnetCommandName} publish failed to exit after {timeout.TotalMinutes} minutes";
logger.LogError(message); logger.LogError(message);
throw new Exception(message); throw new Exception(message);
} }

View File

@ -179,6 +179,11 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
/// </summary> /// </summary>
public Action<DeploymentParameters> UserAdditionalCleanup { get; set; } public Action<DeploymentParameters> UserAdditionalCleanup { get; set; }
/// <summary>
/// Timeout for publish
/// </summary>
public TimeSpan? PublishTimeout { get; set; }
public override string ToString() public override string ToString()
{ {
return string.Format( return string.Format(

View File

@ -37,6 +37,7 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests
ApplicationType = ApplicationType.Standalone, ApplicationType = ApplicationType.Standalone,
PublishApplicationBeforeDeployment = true, PublishApplicationBeforeDeployment = true,
RestoreDependencies = true, RestoreDependencies = true,
PublishTimeout = TimeSpan.FromMinutes(10), // Machines are slow (these tests restore)
StatusMessagesEnabled = false StatusMessagesEnabled = false
}; };