feat: wire ExternalSystem, Database, and Notify APIs into script runtime

IServiceProvider now flows through the actor chain (DeploymentManagerActor
→ InstanceActor → ScriptActor → ScriptExecutionActor) so scripts can
resolve IExternalSystemClient, IDatabaseGateway, and
INotificationDeliveryService from DI. ScriptGlobals exposes ExternalSystem,
Database, Notify, and Scripts as top-level properties so scripts can use
them without the Instance. prefix.
This commit is contained in:
Joseph Doherty
2026-03-18 02:41:18 -04:00
parent 8095c8efbe
commit 899dec6b6f
12 changed files with 767 additions and 100 deletions

View File

@@ -3,16 +3,7 @@ using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ScadaLink.ClusterInfrastructure;
using ScadaLink.Communication;
using ScadaLink.DataConnectionLayer;
using ScadaLink.ExternalSystemGateway;
using ScadaLink.HealthMonitoring;
using ScadaLink.Host;
using ScadaLink.NotificationService;
using ScadaLink.SiteEventLogging;
using ScadaLink.SiteRuntime;
using ScadaLink.StoreAndForward;
namespace ScadaLink.Host.Tests;
@@ -83,35 +74,12 @@ public class HostStartupTests : IDisposable
["ScadaLink:Node:Role"] = "Site",
["ScadaLink:Node:NodeHostname"] = "test-site",
["ScadaLink:Node:SiteId"] = "TestSite",
["ScadaLink:Node:RemotingPort"] = "8082",
["ScadaLink:Node:RemotingPort"] = "0",
});
});
builder.ConfigureServices((context, services) =>
{
// Shared components
services.AddClusterInfrastructure();
services.AddCommunication();
services.AddHealthMonitoring();
services.AddExternalSystemGateway();
services.AddNotificationService();
// Site-only components
services.AddSiteRuntime();
services.AddDataConnectionLayer();
services.AddStoreAndForward();
services.AddSiteEventLogging();
// Options binding (mirrors Program.cs site path)
services.Configure<NodeOptions>(context.Configuration.GetSection("ScadaLink:Node"));
services.Configure<ClusterOptions>(context.Configuration.GetSection("ScadaLink:Cluster"));
services.Configure<DatabaseOptions>(context.Configuration.GetSection("ScadaLink:Database"));
services.Configure<CommunicationOptions>(context.Configuration.GetSection("ScadaLink:Communication"));
services.Configure<HealthMonitoringOptions>(context.Configuration.GetSection("ScadaLink:HealthMonitoring"));
services.Configure<NotificationOptions>(context.Configuration.GetSection("ScadaLink:Notification"));
services.Configure<LoggingOptions>(context.Configuration.GetSection("ScadaLink:Logging"));
services.Configure<DataConnectionOptions>(context.Configuration.GetSection("ScadaLink:DataConnection"));
services.Configure<StoreAndForwardOptions>(context.Configuration.GetSection("ScadaLink:StoreAndForward"));
services.Configure<SiteEventLogOptions>(context.Configuration.GetSection("ScadaLink:SiteEventLog"));
SiteServiceRegistration.Configure(services, context.Configuration);
});
var host = builder.Build();
@@ -134,20 +102,12 @@ public class HostStartupTests : IDisposable
["ScadaLink:Node:Role"] = "Site",
["ScadaLink:Node:NodeHostname"] = "test-site",
["ScadaLink:Node:SiteId"] = "TestSite",
["ScadaLink:Node:RemotingPort"] = "8082",
["ScadaLink:Node:RemotingPort"] = "0",
});
});
builder.ConfigureServices((context, services) =>
{
services.AddClusterInfrastructure();
services.AddCommunication();
services.AddHealthMonitoring();
services.AddExternalSystemGateway();
services.AddNotificationService();
services.AddSiteRuntime();
services.AddDataConnectionLayer();
services.AddStoreAndForward();
services.AddSiteEventLogging();
SiteServiceRegistration.Configure(services, context.Configuration);
});
var host = builder.Build();