Skip to content
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 @@ -5,7 +5,7 @@
using System.IO;
using System.Linq;
using System.Reflection;
#if NETCOREAPP2_1
#if NETCOREAPP
using System.Runtime.Loader;
#endif
using Microsoft.Extensions.CommandLineUtils;
Expand Down Expand Up @@ -69,7 +69,7 @@ protected override int Execute()
}
}

#if NETCOREAPP2_1
#if NETCOREAPP
AssemblyLoadContext.Default.Resolving += (loadContext, assemblyName) =>
{
var name = assemblyName.Name;
Expand Down
107 changes: 107 additions & 0 deletions src/Tools/GetDocumentInsider/src/Commands/GetDocumentCommandWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Tools.Internal;
#if NET7_0_OR_GREATER
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http.Features;
#endif

namespace Microsoft.Extensions.ApiDescription.Tool.Commands;

Expand Down Expand Up @@ -53,6 +60,88 @@ public int Process()
return 3;
}

#if NET7_0_OR_GREATER
// Register no-op implementations of IServer and IHostLifetime
// to prevent the application server from actually launching after build.
void ConfigureHostBuilder(object hostBuilder)
{
((IHostBuilder)hostBuilder).ConfigureServices((context, services) =>
{
services.AddSingleton<IServer, NoopServer>();
services.AddSingleton<IHostLifetime, NoopHostLifetime>();
});
}

// Register a TCS to be invoked when the entrypoint (aka Program.Main)
// has finished running. For minimal APIs, this means that all app.X
// calls about the host has been built have been executed.
var waitForStartTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
void OnEntryPointExit(Exception exception)
{
// If the entry point exited, we'll try to complete the wait
if (exception != null)
{
waitForStartTcs.TrySetException(exception);
}
else
{
waitForStartTcs.TrySetResult(null);
}
}

// Resolve the host factory, ensuring that we don't stop the
// application after the host has been built.
var factory = HostFactoryResolver.ResolveHostFactory(assembly,
stopApplication: false,
configureHostBuilder: ConfigureHostBuilder,
entrypointCompleted: OnEntryPointExit);

if (factory == null)
{
_reporter.WriteError(Resources.FormatMethodsNotFound(
HostFactoryResolver.BuildWebHost,
HostFactoryResolver.CreateHostBuilder,
HostFactoryResolver.CreateWebHostBuilder,
entryPointType));

return 8;
}

try
{
// Retrieve the service provider from the target host.
var services = ((IHost)factory(new[] { $"--{HostDefaults.ApplicationKey}={assemblyName}" })).Services;
if (services == null)
{
_reporter.WriteError(Resources.FormatServiceProviderNotFound(
typeof(IServiceProvider),
HostFactoryResolver.BuildWebHost,
HostFactoryResolver.CreateHostBuilder,
HostFactoryResolver.CreateWebHostBuilder,
entryPointType));

return 9;
}

// Wait for the application to start to ensure that all configurations
// on the WebApplicationBuilder have been processed.
var applicationLifetime = services.GetRequiredService<IHostApplicationLifetime>();
using (var registration = applicationLifetime.ApplicationStarted.Register(() => waitForStartTcs.TrySetResult(null)))
{
waitForStartTcs.Task.Wait();
var success = GetDocuments(services);
if (!success)
{
return 10;
}
}
}
catch (Exception ex)
{
_reporter.WriteError(ex.ToString());
return 11;
}
#else
try
{
var serviceFactory = HostFactoryResolver.ResolveServiceProviderFactory(assembly);
Expand Down Expand Up @@ -91,6 +180,7 @@ public int Process()
_reporter.WriteError(ex.ToString());
return 7;
}
#endif

return 0;
}
Expand Down Expand Up @@ -303,4 +393,21 @@ private object InvokeMethod(MethodInfo method, object instance, object[] argumen

return result;
}

#if NET7_0_OR_GREATER
private sealed class NoopHostLifetime : IHostLifetime
{
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task WaitForStartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}

private sealed class NoopServer : IServer
{
public IFeatureCollection Features { get; } = new FeatureCollection();
public void Dispose() { }
public Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken) => Task.CompletedTask;
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;

}
#endif
}
6 changes: 5 additions & 1 deletion src/Tools/GetDocumentInsider/src/GetDocument.Insider.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<IsPackable>false</IsPackable>
<OutputType>Exe</OutputType>
<RootNamespace>Microsoft.Extensions.ApiDescription.Tool</RootNamespace>
<TargetFrameworks>netcoreapp2.1;$(DefaultNetFxTargetFramework)</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1;$(DefaultNetCoreTargetFramework);$(DefaultNetFxTargetFramework)</TargetFrameworks>
<IsShippingPackage>false</IsShippingPackage>
<Nullable>disable</Nullable>
<NoWarn>$(NoWarn);nullable</NoWarn>
Expand All @@ -15,6 +15,10 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<Reference Include="Microsoft.AspNetCore" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.6.0">
<AllowExplicitReference>true</AllowExplicitReference>
Expand Down
9 changes: 8 additions & 1 deletion src/Tools/dotnet-getdocument/src/Commands/InvokeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,16 @@ protected override int Execute()
projectName,
targetFramework.Version));
}
else if (targetFramework.Version >= new Version(7, 0))
{
toolsDirectory = Path.Combine(thisPath, $"net{targetFramework.Version}");
}
else
{
toolsDirectory = Path.Combine(thisPath, "netcoreapp2.1");
}

executable = DotNetMuxer.MuxerPathOrDefault();
toolsDirectory = Path.Combine(thisPath, "netcoreapp2.1");

args.Add("exec");
args.Add("--depsFile");
Expand Down
2 changes: 1 addition & 1 deletion src/Tools/dotnet-getdocument/src/dotnet-getdocument.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<IsPackable>false</IsPackable>
<OutputType>Exe</OutputType>
<RootNamespace>Microsoft.Extensions.ApiDescription.Tool</RootNamespace>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFrameworks>netcoreapp2.1;$(DefaultNetCoreTargetFramework)</TargetFrameworks>
<UseAppHost>false</UseAppHost>
<IsShippingPackage>false</IsShippingPackage>
</PropertyGroup>
Expand Down