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>
This commit is contained in:
129
RoslynBridge.WebApi/Program.cs
Normal file
129
RoslynBridge.WebApi/Program.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
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();
|
||||
Reference in New Issue
Block a user