Skip to content

Web Hosting

ASP.NET applications often end up with a bloated Program.cs where every cross-cutting concern — authentication, CORS, Swagger, logging, health checks — is mixed together. Shiny Web Hosting lets you break that apart into modular IWebModule classes, each responsible for its own service registration and middleware configuration, keeping your startup clean.

  • GitHub stars for shinyorg/extensions
  • NuGet package Shiny.Extensions.WebHosting
  • Modular IWebModule interface — combines service registration and middleware configuration in one class
  • Explicit registration for reflection-free, AOT-compatible setups
  • Clean separation of concerns — one module per infrastructure component
  1. Install the NuGet package:

    Terminal window
    dotnet add package Shiny.Extensions.WebHosting
  2. Create web modules for each concern:

    using Shiny;
    public class SwaggerModule : IWebModule
    {
    public void Add(WebApplicationBuilder builder)
    {
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    }
    public void Use(WebApplication app)
    {
    if (app.Environment.IsDevelopment())
    {
    app.UseSwagger();
    app.UseSwaggerUI();
    }
    }
    }
  3. Wire up modules in Program.cs:

    using Shiny;
    var builder = WebApplication.CreateBuilder(args);
    builder.AddInfrastructureModules(new SwaggerModule());
    var app = builder.Build();
    app.UseInfrastructureModules();
    app.Run();

Each module implements IWebModule with two methods:

  • Add(WebApplicationBuilder builder) — register services, configuration, and anything that happens before Build()
  • Use(WebApplication app) — configure middleware, endpoints, and anything that happens after Build()
public class CorsModule : IWebModule
{
public void Add(WebApplicationBuilder builder)
{
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
}
public void Use(WebApplication app)
{
app.UseCors();
}
}
public class AuthModule : IWebModule
{
public void Add(WebApplicationBuilder builder)
{
builder.Services.AddAuthentication()
.AddJwtBearer();
builder.Services.AddAuthorization();
}
public void Use(WebApplication app)
{
app.UseAuthentication();
app.UseAuthorization();
}
}
public class HealthCheckModule : IWebModule
{
public void Add(WebApplicationBuilder builder)
{
builder.Services.AddHealthChecks();
}
public void Use(WebApplication app)
{
app.MapHealthChecks("/health");
}
}

Pass explicit module instances — no reflection, fully AOT-compatible:

builder.AddInfrastructureModules(
new SwaggerModule(),
new CorsModule(),
new AuthModule(),
new HealthCheckModule()
);

The end result is a minimal Program.cs:

using Shiny;
var builder = WebApplication.CreateBuilder(args);
builder.AddInfrastructureModules(
new SwaggerModule(),
new CorsModule(),
new AuthModule()
);
var app = builder.Build();
app.UseInfrastructureModules();
app.Run();

All the complexity lives in focused, testable module classes instead of a single monolithic startup file.

An AI skill is available for Shiny Web Hosting to help generate IWebModule classes, configure middleware, and follow best practices directly in your IDE.

Claude Code

Terminal window
claude plugin add github:shinyorg/skills

GitHub Copilot — Copy the shiny-web-hosting skill file into your repository’s custom instructions.