koan-bootstrap
Auto-registration via KoanAutoRegistrar, minimal Program.cs, "Reference = Intent" pattern
- Category: discovered
- Tags: github, community
- Version: 1.0.0
- Author: walid
- Downloads: 0
- GitHub stars: 2
- Updated: 2025-11-21
Download the latest version (v1.0.0) from this page.
SKILL.md
---
name: koan-bootstrap
description: Auto-registration via KoanAutoRegistrar, minimal Program.cs, "Reference = Intent" pattern
---
# Koan Bootstrap & Auto-Registration
## Core Principle
**`services.AddKoan()` is the ONLY line needed in Program.cs.** The framework discovers and registers everything through auto-registration. No manual service registration. No manual configuration. Just add package references and everything wires up automatically.
## Revolutionary "Reference = Intent" Pattern
Adding a package reference **automatically enables functionality**:
```xml
<!-- Add MongoDB connector -->
<PackageReference Include="Koan.Data.Connector.Mongo" Version="0.6.3" />
<!-- Now MongoDB is discovered, configured, and available automatically -->
<!-- Add AI capabilities -->
<PackageReference Include="Koan.AI" Version="0.6.3" />
<!-- Now AI services are auto-registered and ready to use -->
```
No manual registration in Program.cs. The framework handles everything.
## Minimal Program.cs Template
```csharp
using Koan.Core;
var builder = WebApplication.CreateBuilder(args);
// ONE LINE - framework handles all dependencies
builder.Services.AddKoan();
var app = builder.Build();
// Middleware auto-configured by framework
app.Run();
```
**That's it.** 8 lines total. No manual service registration. No manual middleware configuration. The framework discovers:
- Data adapters
- AI providers
- Authentication providers
- Entity controllers
- Background services
- Message queues
- Everything else
## When This Skill Applies
Invoke this skill when:
- ✅ Setting up new projects
- ✅ Debugging initialization issues
- ✅ Adding framework modules
- ✅ Troubleshooting boot failures
- ✅ Creating application-specific services
- ✅ Understanding assembly discovery
## KoanAutoRegistrar Pattern
### What It Is
`KoanAutoRegistrar` is how you register **application-specific services** (not framework services - those auto-register). Create one per application/module.
### When to Create One
Create `KoanAutoRegistrar` when you have:
- Application-specific business logic services
- Custom background workers
- Domain-specific infrastructure
- Third-party service integrations
### Template
```csharp
// File: /Initialization/KoanAutoRegistrar.cs
using Koan.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
namespace MyApp.Initialization;
public sealed class KoanAutoRegistrar : IKoanAutoRegistrar
{
public string ModuleName => "MyApp";
public string? ModuleVersion =>
typeof(KoanAutoRegistrar).Assembly.GetName().Version?.ToString();
public void Initialize(IServiceCollection services)
{
// Register application-specific services here
services.AddScoped<ITodoService, TodoService>();
services.AddScoped<IEmailService, EmailService>();
services.AddSingleton<ICacheService, RedisCacheService>();
services.AddHostedService<BackgroundCleanupWorker>();
}
public void Describe(BootReport report, IConfiguration cfg, IHostEnvironment env)
{
report.AddModule(ModuleName, ModuleVersion);
report.AddNote("Application services registered");
report.AddNote(quot;Environment: {env.EnvironmentName}");
}
}
```
### Discovery Rules
The framework automatically discovers `IKoanAutoRegistrar` implementations:
1. **Assembly Scanning**: Scans all loaded assemblies at startup
2. **Interface Detection**: Finds types implementing `IKoanAutoRegistrar`
3. **Instantiation**: Creates instance and calls `Initialize()`
4. **Boot Reporting**: Calls `Describe()` to populate boot report
**You don't call it.** The framework finds and executes it automatically.
## What NOT to Do
### ❌ WRONG: Manual Service Registration in Program.cs
```csharp
var builder = WebApplication.CreateBuilder(args);
// ❌ DON'T DO THIS - breaks auto-registration pattern
builder.Services.AddScoped<ITodoRepository, TodoRepository>();
builder.Services.AddDbContext<MyDbContext>();
builder.Services.AddScoped<ITodoService, TodoService>();
builder.Services.AddKoan(); // Too late, order matters
```
**Why wrong?**
- Breaks "Reference = Intent" pattern
- Creates registration order dependencies
- Duplicates framework auto-registration
- Makes Program.cs grow uncontrollably
### ✅ CORRECT: Use KoanAutoRegistrar
```csharp
// Program.cs stays minimal
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddKoan();
var app = builder.Build();
app.Run();
// Application services in KoanAutoRegistrar
public sealed class KoanAutoRegistrar : IKoanAutoRegistrar
{
public void Initialize(IServiceCollection services)
{
services.AddScoped<ITodoService, TodoService>();
}
}
```
### ❌ WRONG: Multiple AddKoan() Calls
```csharp
// ❌ DON'T DO THIS
builder.Services.AddKoan();
builder.Services.AddKoanData(); // Redundant
builder.Services.AddKoanWeb(); // Redundant
builder.Services.AddKoanAI(); // Redundant
```
**Why wrong?** `AddKoan()` already discovers and registers ALL Koan modules automatically.
### ✅ CORRECT: Single AddKoan()
```csharp
builder.Services.AddKoan(); // Discovers and registers everything
```
## Boot Report & Diagnostics
### Viewing Boot Report
```csharp
// In Development environment
if (KoanEnv.IsDevelopment)
{
var logger = app.Services.GetRequiredService<ILogger<Program>>();
KoanEnv.DumpSnapshot(logger);
}
```
**Output shows:**
```
[INFO] Koan:discover postgresql: server=localhost;database=myapp... OK
[INFO] Koan:modules data→postgresql
[INFO] Koan:modules web→controllers
[INFO] Koan:modules ai→openai
[INFO] Koan:modules MyApp v1.0.0
```
### Boot Report Structure
```csharp
public void Describe(BootReport report, IConfiguration cfg, IHostEnvironment env)
{
// Add module to report
report.AddModule(ModuleName, ModuleVersion);
// Add informational notes
report.AddNote("Services registered: TodoService, EmailService");
report.AddNote(quot;Data source: {cfg["Koan:Data:Sources:Default:Adapter"]}");
// Add warnings if needed
if (!cfg.GetSection("Email:Smtp").Exists())
{
report.AddWarning("Email configuration missing - notifications disabled");
}
}
```
## Environment Detection
Use `KoanEnv` for environment-aware logic:
```csharp
public void Initialize(IServiceCollection services)
{
// Development-only services
if (KoanEnv.IsDevelopment)
{
services.AddScoped<ISeedService, DevelopmentSeedService>();
}
// Production-only services
if (KoanEnv.IsProduction)
{
services.AddSingleton<IEmailService, SendGridEmailService>();
}
// Container-specific configuration
if (KoanEnv.InContainer)
{
services.AddSingleton<IHealthCheckService, ContainerHealthCheck>();
}
// Dangerous operations gated by flag
if (KoanEnv.AllowMagicInProduction)
{
services.AddScoped<IAdminService, AdminService>();
}
}
```
## Configuration Reading
Use framework configuration helpers:
```csharp
public void Initialize(IServiceCollection services)
{
var sp = services.BuildServiceProvider();
var cfg = sp.GetRequiredService<IConfiguration>();
// Read with fallback chain: setting → env var → default
var apiKey = Configuration.Read(
cfg,
defaultValue: "dev-key",
"App:ApiKey", // Config path
"APP_API_KEY" // Environment variable
);
services.AddSingleton(new ExternalApiClient(apiKey));
}
```
## Debugging Bootstrap Issues
### Symptom: Service Not Found
```
System.InvalidOperationException: Unable to resolve service for type 'ITodoService'
```
**Cause:** `KoanAutoRegistrar` not discovered or not registering service
**Solution:**
1. Verify file exists at `/Initialization/KoanAutoRegistrar.cs`
2. Verify class implements `IKoanAutoRegistrar`
3. Verify class is `public` and not `internal`
4. Check boot logs for module registration
### Symptom: Provider Not Available
```
[ERROR] Koan:discover mongodb: connection failed
[INFO] Koan:modules data→json (fallback)
```
**Cause:** Provider package referenced but connection failed
**Solution:**
1. Verify connection string in `appsettings.json`
2. Check service is running (Docker, local install)
3. Verify network connectivity
4. Check boot report for detailed error
### Symptom: Assembly Not Loaded
```
[WARNING] Koan:modules MyModule not discovered
```
**Cause:** Assembly not referenced or not loaded at startup
**Solution:**
1. Verify `<ProjectReference>` or `<PackageReference>` exists
2. Check assembly is copied to output directory
3. Add explicit assembly reference if needed:
```csharp
var assembly = Assembly.Load("MyModule");
```
## Bundled Templates
- `templates/Program.cs.template` - Minimal Program.cs
- `templates/KoanAutoRegistrar.cs.template` - Complete registrar template
- `templates/KoanAutoRegistrar-with-options.cs.template` - Registrar with configuration options
- `templates/appsettings.json.template` - Koan configuration structure
## Reference Documentation
- **Full Guide:** `docs/guides/deep-dive/bootstrap-lifecycle.md`
- **Troubleshooting:** `docs/guides/troubleshooting/bootstrap-failures.md`
- **Auto-Provisioning:** `docs/guides/deep-dive/auto-provisioning-system.md`
- **Sample:** `samples/S0.ConsoleJsonRepo/Program.cs` (Minimal 20-line bootstrap)
- **Sample:** `samples/S1.Web/Program.cs` (Web bootstrap with lifecycle)
## Advanced: Module Loading Order
Modules load in this order:
1. **Core** - Foundation services
2. **Data** - Repository abstractions
3. **Adapters** - Concrete providers (Mongo, Postgres, etc.)
4. **Domain** - Entity registrations
5. **Web** - Controllers, middleware
6. **Application** - Your `KoanAutoRegistrar`
Dependencies are resolved automatically. You never need to specify order manually.
## Advanced: Conditional Registration
```csharp
public void Initialize(IServiceCollection services)
{
var sp = services.BuildServiceProvider();
var cfg = sp.GetRequiredService<IConfiguration>();
// Feature flags
if (cfg.GetValue<bool>("Features:EmailNotifications"))
{
services.AddScoped<INotificationService, EmailNotificationService>();
}
else
{
services.AddScoped<INotificationService, NoOpNotificationService>();
}
// Provider-specific services
var dataProvider = cfg["Koan:Data:Sources:Default:Adapter"];
if (dataProvider == "mongodb")
{
services.AddSingleton<IMongoIndexManager, MongoIndexManager>();
}
}
```
## Framework Compliance
Bootstrap patterns are **mandatory** in Koan Framework:
- ✅ Use `AddKoan()` for all framework registration
- ✅ Use `KoanAutoRegistrar` for application services
- ✅ Keep Program.cs minimal (under 20 lines)
- ❌ Never manually register framework services
- ❌ Never duplicate framework configuration
- ❌ Never call `AddDbContext`, `AddControllers`, etc. manually
The framework handles everything through auto-discovery.