A .NET 10 library providing shared runtime types and a Roslyn incremental source generator for Farsight-style hosted applications. The generator discovers annotated types and auto-registers services and configuration bindings at compile time, eliminating runtime reflection and manual DI registration. Fully compatible with AOT compilation.
- Compile-time service registration — Annotated singletons and options are registered via source generation
- Zero runtime reflection — All discovery happens at build time
- AOT compatible — No reflection-based code paths; safe for native AOT publishing
- Strict configuration binding — Unknown configuration keys fail at startup
- Validation support — Data annotations and FluentValidation integration
dotnet add package Farsight.Commonusing Farsight.Common;
using System.ComponentModel.DataAnnotations;
[ConfigOption(SectionName = "MyApp")]
public class AppOptions
{
[Required]
public string Endpoint { get; set; } = string.Empty;
}using Farsight.Common;
public sealed partial class Worker : Singleton
{
[Inject]
private readonly AppOptions _options;
protected override Task RunAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Running on: {Endpoint}", _options.Endpoint);
return Task.CompletedTask;
}
}using Farsight.Common;
using Farsight.Common.Startup;
var builder = Host.CreateApplicationBuilder(args);
builder.AddApplication<BasicFarsightStartup>();
await builder.Build().RunAsync();| Attribute | What It Does |
|---|---|
[ConfigOption] |
Binds config section → options class with validation |
[ConfigOption<TValidator>] |
Adds FluentValidation support |
Singleton (base class) |
Registers as singleton + generates constructor injection |
[Inject] |
Auto-wires dependencies into private fields |
BasicFarsightStartup orchestrates your Singleton services through three phases:
- Setup — Parallel preparation work
- Initialize — Ordered initialization
- Run — Long-running execution
public sealed partial class MyService : Singleton
{
protected override Task SetupAsync(CancellationToken ct)
=> Task.CompletedTask;
protected override Task InitializeAsync(CancellationToken ct)
=> Task.CompletedTask;
protected override Task RunAsync(CancellationToken ct)
=> Task.CompletedTask;
}[ConfigOption<MyOptionsValidator>(SectionName = "Features")]
public class MyOptions
{
public string Value { get; set; } = string.Empty;
}
public class MyOptionsValidator : AbstractValidator<MyOptions>
{
public MyOptionsValidator() => RuleFor(x => x.Value).NotEmpty();
}For EF tooling or design-time scenarios:
builder.AddApplicationOptions(); // Only config, no services- .NET 10.0+
- The source generator is included automatically
MIT License — see LICENSE for details.