/// <summary>
 /// Adds a <see cref="ProcessUptimeHealthCheck"/> to the builder registrations.
 /// </summary>
 /// <param name="builder">The <see cref="IHealthCheckRunnerBuilder"/>.</param>
 /// <param name="componentName">
 /// The name of the logical downstream dependency or sub-component of a service. Defaults to 'process'.
 /// Must not contain a colon.
 /// </param>
 /// <param name="measurementName">
 /// The name of the measurement that the status is reported for. Defaults to 'uptime'. Must not
 /// contain a colon.
 /// </param>
 /// <param name="componentType">The type of the component. Defaults to 'system'.</param>
 /// <param name="componentId">
 /// A unique identifier of an instance of a specific sub-component/dependency of a service.
 /// </param>
 /// <returns>The <see cref="IHealthCheckRunnerBuilder"/>.</returns>
 public static IHealthCheckRunnerBuilder AddProcessUptimeHealthCheck(this IHealthCheckRunnerBuilder builder,
                                                                     string componentName = "process", string measurementName = "uptime",
                                                                     string componentType = "system", string componentId      = null)
 {
     return(builder.AddHealthCheck(serviceProvider =>
                                   new ProcessUptimeHealthCheck(componentName, measurementName, componentType, componentId)));
 }
        /// <summary>
        /// Adds the specified health check to the builder registrations.
        /// </summary>
        /// <typeparam name="THealthCheck">The health check implementation type.</typeparam>
        /// <param name="builder">The <see cref="IHealthCheckRunnerBuilder"/>.</param>
        /// <param name="parameters">Constructor arguments not provided by the <see cref="IServiceProvider"/>.</param>
        /// <returns>The <see cref="IHealthCheckRunnerBuilder"/>.</returns>
        public static IHealthCheckRunnerBuilder AddHealthCheck <THealthCheck>(this IHealthCheckRunnerBuilder builder, params object[] parameters)
            where THealthCheck : class, IHealthCheck
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            return(builder.AddHealthCheck(serviceProvider => ActivatorUtilities.CreateInstance <THealthCheck>(serviceProvider, parameters)));
        }
        /// <summary>
        /// Adds the specified health check to the builder registrations.
        /// </summary>
        /// <param name="builder">The <see cref="IHealthCheckRunnerBuilder"/>.</param>
        /// <param name="healthCheck">An <see cref="IHealthCheck"/> instance.</param>
        /// <returns>The <see cref="IHealthCheckRunnerBuilder"/>.</returns>
        public static IHealthCheckRunnerBuilder AddHealthCheck(this IHealthCheckRunnerBuilder builder, IHealthCheck healthCheck)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }
            if (healthCheck == null)
            {
                throw new ArgumentNullException(nameof(healthCheck));
            }

            return(builder.AddHealthCheck(_ => healthCheck));
        }
        /// <summary>
        /// Adds a <see cref="DiskDriveHealthCheck"/> to the builder registrations.
        /// </summary>
        /// <param name="builder">The <see cref="IHealthCheckRunnerBuilder"/>.</param>
        /// <param name="warnGigabytes">
        /// The the lowest allowable level of available free space in gigabytes, below which results in a <see cref="HealthStatus.Warn"/> status.
        /// </param>
        /// <param name="failGigabytes">
        /// The the lowest allowable level of available free space in gigabytes, below which results in a <see cref="HealthStatus.Fail"/> status.
        /// </param>
        /// <param name="driveName">
        /// The name of the drive on which to check the available free space.
        /// The expected format for the C drive would be 'C:\' (at least on Windows).
        /// The wildcard '*' can be used to return results from all drives.
        /// </param>
        /// <param name="componentName">
        /// The name of the logical downstream dependency or sub-component of a service. Defaults to
        /// 'diskDrive'. Must not contain a colon.
        /// </param>
        /// <param name="measurementName">
        /// The name of the measurement that the status is reported for. Defaults to 'availableFreeSpace'.
        /// Must not contain a colon.
        /// </param>
        /// <param name="componentType">The type of the component. Defaults to 'system'.</param>
        /// <param name="componentId">
        /// A unique identifier of an instance of a specific sub-component/dependency of a service.
        /// </param>
        /// <returns>The <see cref="IHealthCheckRunnerBuilder"/>.</returns>
        public static IHealthCheckRunnerBuilder AddDiskDriveHealthCheck(this IHealthCheckRunnerBuilder builder,
                                                                        double warnGigabytes = 5, double failGigabytes             = .5, string driveName = "*",
                                                                        string componentName = "diskDrive", string measurementName = "availableFreeSpace",
                                                                        string componentType = "system", string componentId        = null)
        {
            if (string.IsNullOrEmpty(driveName))
            {
                throw new ArgumentNullException(nameof(driveName));
            }
            if (warnGigabytes < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(warnGigabytes), "Must not be less than zero.");
            }
            if (failGigabytes < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(failGigabytes), "Must not be less than zero.");
            }

            return(builder.AddHealthCheck(serviceProvider =>
                                          new DiskDriveHealthCheck(warnGigabytes, failGigabytes, driveName, componentName, measurementName, componentType, componentId)));
        }