Femur.Hosting
0.0.31
dotnet add package Femur.Hosting --version 0.0.31
NuGet\Install-Package Femur.Hosting -Version 0.0.31
<PackageReference Include="Femur.Hosting" Version="0.0.31" />
<PackageVersion Include="Femur.Hosting" Version="0.0.31" />
<PackageReference Include="Femur.Hosting" />
paket add Femur.Hosting --version 0.0.31
#r "nuget: Femur.Hosting, 0.0.31"
#:package Femur.Hosting@0.0.31
#addin nuget:?package=Femur.Hosting&version=0.0.31
#tool nuget:?package=Femur.Hosting&version=0.0.31
Femur.Hosting
A fluent builder framework for console applications with structured lifecycle management, comprehensive error handling, and bootstrap logging support.
Installation
dotnet add package Femur.Hosting
Quick Example
using Femur.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
return await ApplicationBuilder.Create(args)
.UseDefaultConsoleLogging()
.ConfigureServices((context, services) =>
{
services.AddHostedService<MyService>();
})
.RunAsync();
class MyService : IHostedService
{
private readonly ILogger<MyService> _logger;
public MyService(ILogger<MyService> logger) => _logger = logger;
public Task StartAsync(CancellationToken ct)
{
_logger.LogInformation("Service started");
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken ct) => Task.CompletedTask;
}
Key Features
Staged Fluent Builder
ApplicationBuilder uses a staged fluent API that guides you through configuration in the correct order:
- Initial → Create builder with args
- Bootstrap → Set up logging (before host initialization)
- Configuration → Load config files, environment variables
- Services → Register services in DI container
- Executable → Build and run the application
Each stage returns a different interface, ensuring type-safe configuration and preventing incorrect usage.
Comprehensive Error Handling
Handle errors at different lifecycle phases with specific handlers:
await ApplicationBuilder.Create(args)
.UseDefaultConsoleLogging()
.ConfigureServices(...)
.OnBuilderError((ex, logger) => ExitCodes.BuilderCreationFailed)
.OnBuildError((ex, logger) => ExitCodes.BuildFailed)
.OnPreStartupError((ex, logger) => ExitCodes.PreStartupError)
.OnRuntimeError((ex, logger) => ExitCodes.RuntimeError)
.OnPostShutdownError((ex, logger) => ExitCodes.PostShutdownError)
.RunAsync();
Exit Codes
Standardized exit codes for operational integration:
| Exit Code | Constant | Meaning |
|---|---|---|
| 0 | Success |
Application completed successfully |
| 1 | BuilderCreationFailed |
Failed to create ApplicationBuilder |
| 2 | BuildFailed |
Failed during configuration or service registration |
| 3 | RuntimeError |
Unhandled exception during execution |
| 4 | PreStartupError |
Failed during host startup initialization |
| 5 | PostShutdownError |
Error during disposal/cleanup |
| 10 | BootstrapLoggerFailed |
Bootstrap logger initialization failed |
| 125 | CommandCancelled |
User cancelled operation |
| 130 | CtrlCInterrupt |
Ctrl+C interrupt signal |
These codes enable Docker, Kubernetes, CI/CD pipelines, and monitoring tools to understand failure reasons.
Bootstrap Logging Integration
Bootstrap logging solves the "blind spot" in .NET Generic Host where logging isn't available during configuration:
await ApplicationBuilder.Create(args)
.UseDefaultConsoleLogging() // Creates BootstrapLogger
.ConfigureConfiguration((context, config) =>
{
// Logs: "Loading configuration..."
config.AddJsonFile("appsettings.json");
})
.ConfigureServices((context, services) =>
{
// Logs: "Registering services..."
services.AddHostedService<MyService>();
})
.RunAsync();
The same logging providers (console, OpenTelemetry, etc.) receive logs from both bootstrap and runtime phases.
Type Discovery
Automatic discovery of the Program type for logger category naming:
// Logger category automatically resolved to "Program" or entry assembly name
.UseDefaultConsoleLogging()
// Equivalent to:
.UseDefaultConsoleLogging<Program>()
Complete Example
using Femur;
using Femur.Hosting;
using FluentValidation;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
return await ApplicationBuilder.Create(args)
// Stage 1: Bootstrap logging
// Logs configuration and service registration
.UseDefaultConsoleLogging()
// Stage 2: Configuration
// Load configuration files
.ConfigureConfiguration((context, config) =>
{
config.AddJsonFile("appsettings.json", optional: false);
config.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true);
config.AddEnvironmentVariables();
})
// Stage 3: Services
// Register services with DI container
.ConfigureServices((context, services) =>
{
// Configuration with validation
services.TryConfigureByConventionWithValidation<AppOptions>();
// Business logic
services.AddHostedService<WorkerService>();
})
// Error handling for each lifecycle phase
.OnBuildError((exception, logger) =>
{
logger.LogCritical(exception, "Configuration or validation failed");
return ExitCodes.BuildFailed;
})
.OnRuntimeError((exception, logger) =>
{
logger.LogCritical(exception, "Unhandled runtime exception");
return ExitCodes.RuntimeError;
})
// Stage 4: Run
.RunAsync();
// Configuration with validation
class AppOptions : IStandardOptions<AppOptions>
{
public static string SectionName => "App";
public string WorkerName { get; set; } = "";
public static void SetupValidator(AbstractValidator<AppOptions> validator)
{
validator.RuleFor(x => x.WorkerName).NotEmpty();
}
}
// Worker service
class WorkerService : IHostedService
{
private readonly AppOptions _options;
private readonly ILogger<WorkerService> _logger;
public WorkerService(IOptions<AppOptions> options, ILogger<WorkerService> logger)
{
_options = options.Value;
_logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Worker {Name} started", _options.WorkerName);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Worker stopped");
return Task.CompletedTask;
}
}
Architecture
ApplicationBuilder Stages
The builder enforces a specific configuration order through interface progression:
IInitialApplicationBuilder Create(args)
↓
IBootstrapApplicationBuilder UseDefaultConsoleLogging()
↓
IConfigurationApplicationBuilder ConfigureConfiguration(...)
↓
IServicesApplicationBuilder ConfigureServices(...)
↓
IExecutableApplicationBuilder OnBuildError(...), OnRuntimeError(...), RunAsync()
Each interface only exposes methods valid for that stage, preventing configuration mistakes.
Error Handling Strategy
Errors are differentiated by lifecycle phase:
- Builder Creation → Before ApplicationBuilder exists
- Build Phase → During configuration and service registration
- Pre-Startup → During
host.RunAsync()initialization - Runtime → During normal application execution
- Post-Shutdown → During disposal and cleanup
Each phase has a dedicated error handler returning an appropriate exit code.
Use Cases
Console Applications
Build structured console applications with proper lifecycle management:
await ApplicationBuilder.Create(args)
.UseDefaultConsoleLogging()
.ConfigureServices(services => services.AddHostedService<ConsoleWorker>())
.RunAsync();
CLI Tools
Command-line tools with validation and error handling:
await ApplicationBuilder.Create(args)
.UseDefaultConsoleLogging()
.ConfigureServices(services =>
{
services.TryConfigureByConventionWithValidation<CliOptions>();
services.AddHostedService<CliExecutor>();
})
.OnBuildError((ex, logger) => ExitCodes.BuildFailed)
.RunAsync();
Scheduled Jobs
Long-running background workers:
await ApplicationBuilder.Create(args)
.UseDefaultConsoleLogging()
.ConfigureServices(services =>
{
services.AddHostedService<ScheduledJobWorker>();
services.AddSingleton<IJobScheduler, QuartzScheduler>();
})
.RunAsync();
Web Applications
For ASP.NET Core applications, use Femur.Hosting.Web which provides WebApplicationBuilder with similar patterns for web scenarios.
See Also
- Full Documentation - Complete Femur documentation
- Getting Started Guide - Step-by-step tutorial
- API Data Aggregator Example - Complete working application
- Core Concepts - Architecture and design principles
- Femur.Logging.Bootstrap - Bootstrap logging details
- Logging Examples - Advanced logging patterns
Package Dependencies
Microsoft.Extensions.Hosting- Generic host infrastructureMicrosoft.Extensions.Logging- Logging abstractionsMicrosoft.Extensions.Configuration- Configuration systemMicrosoft.Extensions.DependencyInjection- DI container
Target Frameworks
- .NET 8.0 (LTS)
- .NET 9.0 (STS)
- .NET 10.0
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Femur.Logging.Bootstrap (>= 0.0.31)
- Microsoft.Extensions.Configuration (>= 10.0.2)
- Microsoft.Extensions.DependencyInjection (>= 10.0.2)
- Microsoft.Extensions.Hosting (>= 10.0.2)
- Microsoft.Extensions.Logging (>= 10.0.2)
- Microsoft.Extensions.Logging.Console (>= 10.0.2)
-
net8.0
- Femur.Logging.Bootstrap (>= 0.0.31)
- Microsoft.Extensions.Configuration (>= 10.0.2)
- Microsoft.Extensions.DependencyInjection (>= 10.0.2)
- Microsoft.Extensions.Hosting (>= 10.0.2)
- Microsoft.Extensions.Logging (>= 10.0.2)
- Microsoft.Extensions.Logging.Console (>= 10.0.2)
-
net9.0
- Femur.Logging.Bootstrap (>= 0.0.31)
- Microsoft.Extensions.Configuration (>= 10.0.2)
- Microsoft.Extensions.DependencyInjection (>= 10.0.2)
- Microsoft.Extensions.Hosting (>= 10.0.2)
- Microsoft.Extensions.Logging (>= 10.0.2)
- Microsoft.Extensions.Logging.Console (>= 10.0.2)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Femur.Hosting:
| Package | Downloads |
|---|---|
|
Femur.Hosting.Web
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.31 | 157 | 3/30/2026 |
| 0.0.30 | 221 | 1/25/2026 |
| 0.0.29 | 172 | 1/19/2026 |
| 0.0.28 | 224 | 12/5/2025 |
| 0.0.27 | 710 | 12/3/2025 |
| 0.0.26 | 737 | 12/3/2025 |
| 0.0.25 | 710 | 12/2/2025 |
| 0.0.24 | 711 | 12/2/2025 |
| 0.0.23 | 706 | 12/2/2025 |
| 0.0.21 | 710 | 12/2/2025 |
| 0.0.20 | 237 | 11/24/2025 |
| 0.0.16 | 374 | 10/6/2025 |
| 0.0.15 | 242 | 10/1/2025 |
| 0.0.14 | 255 | 9/20/2025 |
| 0.0.13 | 265 | 9/19/2025 |