Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API Debt - Microsoft.Extensions.Hosting #76692

Merged
merged 8 commits into from
Oct 14, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public abstract class BackgroundService : IHostedService, IDisposable
/// Triggered when the application host is ready to start the service.
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous Start operation.</returns>
public virtual Task StartAsync(CancellationToken cancellationToken)
Nick-Stanton marked this conversation as resolved.
Show resolved Hide resolved
{
// Create linked token to allow cancelling executing task from provided token
Expand All @@ -58,6 +59,7 @@ public virtual Task StartAsync(CancellationToken cancellationToken)
/// Triggered when the application host is performing a graceful shutdown.
/// </summary>
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous Stop operation.</returns>
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,20 @@ namespace Microsoft.Extensions.Hosting
/// </summary>
public static class Environments
{
/// <summary>
/// Specifies the Development environment.
/// </summary>
/// <remarks>The development environment can enable features that shouldn't be exposed in production. Because of the performance cost, scope validation and dependency validation only happens in development.</remarks>
public static readonly string Development = "Development";
/// <summary>
/// Specifies the Staging environment.
/// </summary>
/// <remarks>The staging environment can be used to validate app changes before changing the environment to production.</remarks>
public static readonly string Staging = "Staging";
/// <summary>
/// Specifies the Production environment.
/// </summary>
/// <remarks>The production environment should be configured to maximize security, performance, and application robustness.</remarks>
public static readonly string Production = "Production";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ namespace Microsoft.Extensions.Hosting
/// </summary>
public class HostBuilderContext
{
/// <summary>
/// Initializes a new instance of <see cref="HostBuilderContext"/>.
/// </summary>
/// <param name="properties">A non-null <see cref="IDictionary{TKey, TValue}"/> for sharing state between components during the host building process.</param>
public HostBuilderContext(IDictionary<object, object> properties)
{
ThrowHelper.ThrowIfNull(properties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

namespace Microsoft.Extensions.Hosting
{
/// <summary>
/// Provides extension methods for the <see cref="IHostBuilder"/> from the hosting abstractions package.
Nick-Stanton marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
public static class HostingAbstractionsHostBuilderExtensions
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

namespace Microsoft.Extensions.Hosting
{
/// <summary>
/// Provides extension methods for the <see cref="IHost"/> from the hosting abstractions package.
/// </summary>
public static class HostingAbstractionsHostExtensions
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public interface IHostBuilder
/// Overrides the factory used to create the service provider.
/// </summary>
/// <typeparam name="TContainerBuilder">The type of builder.</typeparam>
/// <param name="factory">The factory to register.</param>
/// <returns>The same instance of the <see cref="IHostBuilder"/> for chaining.</returns>
IHostBuilder UseServiceProviderFactory<TContainerBuilder>(Func<HostBuilderContext, IServiceProviderFactory<TContainerBuilder>> factory) where TContainerBuilder : notnull;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

namespace Microsoft.Extensions.Hosting
{
/// <summary>
/// Tracks host lifetime.
/// </summary>
public interface IHostLifetime
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ public interface IHostedService
/// Triggered when the application host is ready to start the service.
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous Start operation.</returns>
Task StartAsync(CancellationToken cancellationToken);

/// <summary>
/// Triggered when the application host is performing a graceful shutdown.
/// </summary>
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous Stop operation.</returns>
Task StopAsync(CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public interface ISystemdNotifier
/// <summary>
/// Sends a notification to systemd.
/// </summary>
/// <param name="state">The <see cref="ServiceState"/> to notify.</param>
void Notify(ServiceState state);
/// <summary>
/// Returns whether systemd is configured to receive service notifications.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public struct ServiceState
/// <summary>
/// Create custom ServiceState.
/// </summary>
/// <param name="state">A <see cref="string"/> representation of service state.</param>
public ServiceState(string state)
{
ThrowHelper.ThrowIfNull(state);
Expand All @@ -36,6 +37,7 @@ public ServiceState(string state)
/// <summary>
/// String representation of service state.
/// </summary>
/// <returns>The <see cref="string"/> representation of the service state.</returns>
public override string ToString()
=> _data == null ? string.Empty : Encoding.UTF8.GetString(_data);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

namespace Microsoft.Extensions.Hosting.Systemd
{
/// <summary>
/// Provides notification messages for application started and stopping, and configures console logging to the systemd format.
/// </summary>
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("ios")]
Expand All @@ -19,6 +22,13 @@ public partial class SystemdLifetime : IHostLifetime, IDisposable
private CancellationTokenRegistration _applicationStartedRegistration;
private CancellationTokenRegistration _applicationStoppingRegistration;

/// <summary>
/// Initializes a new <see cref="SystemdLifetime"/> instance.
/// </summary>
/// <param name="environment">Information about the host.</param>
/// <param name="applicationLifetime">The <see cref="IHostApplicationLifetime"/> that tracks the service lifetime.</param>
Nick-Stanton marked this conversation as resolved.
Show resolved Hide resolved
/// <param name="systemdNotifier">The <see cref="ISystemdNotifier"/> to notify Systemd about service status.</param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> used to instantiate the lifetime logger.</param>
public SystemdLifetime(IHostEnvironment environment, IHostApplicationLifetime applicationLifetime, ISystemdNotifier systemdNotifier, ILoggerFactory loggerFactory)
{
ThrowHelper.ThrowIfNull(environment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public class SystemdNotifier : ISystemdNotifier

private readonly string? _socketPath;

/// <summary>
/// Instantiates a new <see cref="SystemdNotifier"/> and sets the notify socket path.
/// </summary>
public SystemdNotifier() :
this(GetNotifySocketPath())
{ }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,36 @@

namespace Microsoft.Extensions.Hosting.WindowsServices
{
/// <summary>
/// Listens for shutdown signal and tracks the status of the Windows service.
/// </summary>
[SupportedOSPlatform("windows")]
public class WindowsServiceLifetime : ServiceBase, IHostLifetime
{
private readonly TaskCompletionSource<object?> _delayStart = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);
private readonly ManualResetEventSlim _delayStop = new ManualResetEventSlim();
private readonly HostOptions _hostOptions;

/// <summary>
/// Initializes a new <see cref="WindowsServiceLifetime"/> instance.
/// </summary>
/// <param name="environment">Information about the host.</param>
/// <param name="applicationLifetime">The <see cref="IHostApplicationLifetime"/> that tracks the service lifetime.</param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> used to instantiate the lifetime logger.</param>
/// <param name="optionsAccessor">The <see cref="IOptions{HostOptions}"/> containing options for the service.</param>
public WindowsServiceLifetime(IHostEnvironment environment, IHostApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory, IOptions<HostOptions> optionsAccessor)
: this(environment, applicationLifetime, loggerFactory, optionsAccessor, Options.Options.Create(new WindowsServiceLifetimeOptions()))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="WindowsServiceLifetime"/> class.
/// </summary>
/// <param name="environment">Information about the host.</param>
/// <param name="applicationLifetime">The <see cref="IHostApplicationLifetime"/> that tracks the service lifetime.</param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> used to instantiate the lifetime logger.</param>
/// <param name="optionsAccessor">The <see cref="IOptions{HostOptions}"/> containing options for the service.</param>
/// <param name="windowsServiceOptionsAccessor">The Windows service options used to find the service name.</param>
public WindowsServiceLifetime(IHostEnvironment environment, IHostApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory, IOptions<HostOptions> optionsAccessor, IOptions<WindowsServiceLifetimeOptions> windowsServiceOptionsAccessor)
{
ThrowHelper.ThrowIfNull(environment);
Expand Down Expand Up @@ -85,14 +103,17 @@ public Task StopAsync(CancellationToken cancellationToken)
}

// Called by base.Run when the service is ready to start.
/// <inheritdoc />
protected override void OnStart(string[] args)
{
_delayStart.TrySetResult(null);
base.OnStart(args);
}

// Called by base.Stop. This may be called multiple times by service Stop, ApplicationStopping, and StopAsync.
// That's OK because StopApplication uses a CancellationTokenSource and prevents any recursion.
/// <summary>
/// Raises the Stop event to stop the <see cref="WindowsServiceLifetime"/>.
/// </summary>
/// <remarks>This might be called multiple times by service Stop, ApplicationStopping, and StopAsync. That's okay because StopApplication uses a CancellationTokenSource and prevents any recursion.</remarks>
protected override void OnStop()
{
ApplicationLifetime.StopApplication();
Expand All @@ -101,6 +122,9 @@ protected override void OnStop()
base.OnStop();
}

/// <summary>
/// Raises the Shutdown event.
/// </summary>
protected override void OnShutdown()
{
ApplicationLifetime.StopApplication();
Expand All @@ -109,6 +133,10 @@ protected override void OnShutdown()
base.OnShutdown();
}

/// <summary>
/// Releases the resources used by the <see cref="WindowsServiceLifetime"/>.
/// </summary>
/// <param name="disposing"><see langword="true" /> only when called from <see cref="IDisposable.Dispose"/>; otherwise, <see langword="false" />.</param>
protected override void Dispose(bool disposing)
{
if (disposing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

namespace Microsoft.Extensions.Hosting
{
/// <summary>
/// Provides option flags for <see cref="Internal.ConsoleLifetime"/>.
/// </summary>
public class ConsoleLifetimeOptions
{
/// <summary>
Expand Down
3 changes: 3 additions & 0 deletions src/libraries/Microsoft.Extensions.Hosting/src/HostBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ public partial class HostBuilder : IHostBuilder
private IServiceProvider? _appServices;
private PhysicalFileProvider? _defaultProvider;

/// <summary>
/// Initializes a new instance of <see cref="HostBuilder"/>.
/// </summary>
[RequiresDynamicCode(Host.RequiresDynamicCodeMessage)]
public HostBuilder()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

namespace Microsoft.Extensions.Hosting
{
/// <summary>
/// Provides extension methods for the <see cref="IHostBuilder"/> from the hosting package.
Nick-Stanton marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
public static class HostingHostBuilderExtensions
{
/// <summary>
Expand Down Expand Up @@ -64,7 +67,7 @@ public static IHostBuilder UseContentRoot(this IHostBuilder hostBuilder, string
/// Specify the <see cref="IServiceProvider"/> to be the default one.
/// </summary>
/// <param name="hostBuilder">The <see cref="IHostBuilder"/> to configure.</param>
/// <param name="configure"></param>
/// <param name="configure">The delegate that configures the <see cref="IServiceProvider"/>.</param>
/// <returns>The <see cref="IHostBuilder"/>.</returns>
[RequiresDynamicCode(Host.RequiresDynamicCodeMessage)]
public static IHostBuilder UseDefaultServiceProvider(this IHostBuilder hostBuilder, Action<ServiceProviderOptions> configure)
Expand Down Expand Up @@ -161,7 +164,7 @@ public static IHostBuilder ConfigureServices(this IHostBuilder hostBuilder, Acti
/// Enables configuring the instantiated dependency container. This can be called multiple times and
/// the results will be additive.
/// </summary>
/// <typeparam name="TContainerBuilder"></typeparam>
/// <typeparam name="TContainerBuilder">The type of builder.</typeparam>
/// <param name="hostBuilder">The <see cref="IHostBuilder" /> to configure.</param>
/// <param name="configureDelegate">The delegate for configuring the <typeparamref name="TContainerBuilder"/>.</param>
/// <returns>The same instance of the <see cref="IHostBuilder"/> for chaining.</returns>
Expand Down