Files
AJ Isaacs 1cbfba3893 Add WebAPI middleware for multi-instance Roslyn Bridge routing
Add RoslynBridge.WebApi - ASP.NET Core 8.0 middleware that:
- Provides a centralized REST API for accessing multiple VS instances
- Manages instance registry with discovery by port, solution, or PID
- Proxies requests to the appropriate VS instance
- Tracks request/response history for debugging
- Auto-cleanup of stale instances via background service

Features:
- Health endpoints: /api/health, /api/health/ping
- Roslyn endpoints: /api/roslyn/projects, /api/roslyn/diagnostics, etc.
- Instance management: /api/instances (register, heartbeat, unregister)
- History tracking: /api/history, /api/history/stats
- Swagger UI at root (/) for API documentation
- CORS enabled for web applications

Services:
- InstanceRegistryService: Thread-safe registry of VS instances
- HistoryService: In-memory request/response history (max 1000 entries)
- InstanceCleanupService: Background service to remove stale instances
- RoslynBridgeClient: HTTP client for proxying to VS instances

Update RoslynBridge.sln to include RoslynBridge.WebApi project.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-26 23:51:33 -04:00

130 lines
3.7 KiB
C#

using Microsoft.OpenApi.Models;
using RoslynBridge.WebApi.Middleware;
using RoslynBridge.WebApi.Services;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
// Add Windows Service support
builder.Services.AddWindowsService(options =>
{
options.ServiceName = "RoslynBridge Web API";
});
// Configure CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
// Add controllers
builder.Services.AddControllers();
// Register history service as singleton for in-memory storage
builder.Services.AddSingleton<IHistoryService, HistoryService>();
// Register instance registry service as singleton
builder.Services.AddSingleton<IInstanceRegistryService, InstanceRegistryService>();
// Register background service for cleaning up stale instances
builder.Services.AddHostedService<InstanceCleanupService>();
// Configure HttpClient for Roslyn Bridge
var roslynBridgeUrl = builder.Configuration.GetValue<string>("RoslynBridge:BaseUrl") ?? "http://localhost:59123";
builder.Services.AddHttpClient<IRoslynBridgeClient, RoslynBridgeClient>(client =>
{
client.BaseAddress = new Uri(roslynBridgeUrl);
client.Timeout = TimeSpan.FromSeconds(30);
});
// Configure Swagger/OpenAPI
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Roslyn Bridge Web API",
Version = "v1.0",
Description = "Modern web API middleware for Roslyn Bridge - connecting Claude AI to Visual Studio code analysis",
Contact = new OpenApiContact
{
Name = "Roslyn Bridge",
Url = new Uri("https://github.com/yourusername/roslynbridge")
}
});
// Include XML comments for better documentation
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFilename);
if (File.Exists(xmlPath))
{
options.IncludeXmlComments(xmlPath);
}
// Add operation tags
options.TagActionsBy(api =>
{
if (api.GroupName != null)
{
return new[] { api.GroupName };
}
if (api.ActionDescriptor is Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor controllerActionDescriptor)
{
return new[] { controllerActionDescriptor.ControllerName };
}
return new[] { "Unknown" };
});
});
// Add health checks
builder.Services.AddHealthChecks();
var app = builder.Build();
// Configure the HTTP request pipeline
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Enable Swagger in all environments for easy access
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Roslyn Bridge API v1");
options.RoutePrefix = string.Empty; // Serve Swagger UI at root
options.DocumentTitle = "Roslyn Bridge API";
options.DisplayRequestDuration();
});
app.UseHttpsRedirection();
// Enable CORS
app.UseCors("AllowAll");
// Enable history tracking middleware (must be before authorization and controllers)
app.UseHistoryTracking();
app.UseAuthorization();
// Map controllers
app.MapControllers();
// Map health check endpoint
app.MapHealthChecks("/health");
// Log startup information
var logger = app.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Roslyn Bridge Web API started");
logger.LogInformation("Swagger UI available at: {Url}", app.Environment.IsDevelopment() ? "https://localhost:7001" : "/");
logger.LogInformation("Connected to Roslyn Bridge at: {Url}", roslynBridgeUrl);
app.Run();