diff --git a/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs b/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs
index 5cfafa6a5..b950f9f49 100644
--- a/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs
+++ b/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs
@@ -95,35 +95,29 @@ public interface IWebServerService : IArtemisService
/// Adds a new Web API controller and restarts the web server
///
/// The type of Web API controller to remove
- void AddController(PluginFeature feature) where T : WebApiController;
+ WebApiControllerRegistration AddController(PluginFeature feature) where T : WebApiController;
///
/// Removes an existing Web API controller and restarts the web server
///
/// The type of Web API controller to remove
- void RemoveController() where T : WebApiController;
+ void RemoveController(WebApiControllerRegistration registration);
///
/// Adds a new EmbedIO module and restarts the web server
///
- void AddModule(PluginFeature feature, Func create);
+ WebModuleRegistration AddModule(PluginFeature feature, Func create);
///
/// Removes a EmbedIO module and restarts the web server
///
- void RemoveModule(Func create);
+ void RemoveModule(WebModuleRegistration create);
///
/// Adds a new EmbedIO module and restarts the web server
///
/// The type of module to add
- void AddModule(PluginFeature feature) where T : IWebModule;
-
- ///
- /// Removes a EmbedIO module and restarts the web server
- ///
- /// The type of module to remove
- void RemoveModule() where T : IWebModule;
+ WebModuleRegistration AddModule(PluginFeature feature) where T : IWebModule;
///
/// Occurs when the web server has been created and is about to start. This is the ideal place to add your own modules.
diff --git a/src/Artemis.Core/Services/WebServer/WebApiControllerRegistration.cs b/src/Artemis.Core/Services/WebServer/WebApiControllerRegistration.cs
index 1a6375a11..4a2c7bb50 100644
--- a/src/Artemis.Core/Services/WebServer/WebApiControllerRegistration.cs
+++ b/src/Artemis.Core/Services/WebServer/WebApiControllerRegistration.cs
@@ -3,26 +3,55 @@ using EmbedIO.WebApi;
namespace Artemis.Core.Services;
-internal class WebApiControllerRegistration : WebApiControllerRegistration where T : WebApiController
+///
+/// Represents a web API controller registration.
+///
+/// The type of the web API controller.
+public class WebApiControllerRegistration : WebApiControllerRegistration where T : WebApiController
{
- public WebApiControllerRegistration(PluginFeature feature) : base(feature, typeof(T))
+ internal WebApiControllerRegistration(IWebServerService webServerService, PluginFeature feature) : base(webServerService, feature, typeof(T))
{
Factory = () => feature.Plugin.Resolve();
}
- public Func Factory { get; set; }
- public override object UntypedFactory => Factory;
+ internal Func Factory { get; set; }
+ internal override object UntypedFactory => Factory;
}
-internal abstract class WebApiControllerRegistration
+///
+/// Represents a web API controller registration.
+///
+public abstract class WebApiControllerRegistration
{
- protected WebApiControllerRegistration(PluginFeature feature, Type controllerType)
+ private readonly IWebServerService _webServerService;
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ protected internal WebApiControllerRegistration(IWebServerService webServerService, PluginFeature feature, Type controllerType)
{
+ _webServerService = webServerService;
Feature = feature;
ControllerType = controllerType;
+
+ Feature.Disabled += FeatureOnDisabled;
}
- public abstract object UntypedFactory { get; }
- public Type ControllerType { get; set; }
+ private void FeatureOnDisabled(object? sender, EventArgs e)
+ {
+ _webServerService.RemoveController(this);
+ Feature.Disabled -= FeatureOnDisabled;
+ }
+
+ internal abstract object UntypedFactory { get; }
+
+ ///
+ /// Gets the type of the web API controller.
+ ///
+ public Type ControllerType { get; }
+
+ ///
+ /// Gets the plugin feature that provided the web API controller.
+ ///
public PluginFeature Feature { get; }
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/WebServer/WebModuleRegistration.cs b/src/Artemis.Core/Services/WebServer/WebModuleRegistration.cs
index 270a5ec4d..dca340b35 100644
--- a/src/Artemis.Core/Services/WebServer/WebModuleRegistration.cs
+++ b/src/Artemis.Core/Services/WebServer/WebModuleRegistration.cs
@@ -3,25 +3,44 @@ using EmbedIO;
namespace Artemis.Core.Services;
-internal class WebModuleRegistration
+///
+/// Represents a registration for a web module.
+///
+public class WebModuleRegistration
{
- public WebModuleRegistration(PluginFeature feature, Type webModuleType)
+ private readonly IWebServerService _webServerService;
+
+ internal WebModuleRegistration(IWebServerService webServerService, PluginFeature feature, Type webModuleType)
{
+ _webServerService = webServerService;
Feature = feature ?? throw new ArgumentNullException(nameof(feature));
WebModuleType = webModuleType ?? throw new ArgumentNullException(nameof(webModuleType));
+
+ Feature.Disabled += FeatureOnDisabled;
}
- public WebModuleRegistration(PluginFeature feature, Func create)
+ internal WebModuleRegistration(IWebServerService webServerService, PluginFeature feature, Func create)
{
+ _webServerService = webServerService;
Feature = feature ?? throw new ArgumentNullException(nameof(feature));
Create = create ?? throw new ArgumentNullException(nameof(create));
+
+ Feature.Disabled += FeatureOnDisabled;
}
+ ///
+ /// The plugin feature that provided the web module.
+ ///
public PluginFeature Feature { get; }
- public Type? WebModuleType { get; }
- public Func? Create { get; }
- public IWebModule CreateInstance()
+ ///
+ /// The type of the web module.
+ ///
+ public Type? WebModuleType { get; }
+
+ internal Func? Create { get; }
+
+ internal IWebModule CreateInstance()
{
if (Create != null)
return Create();
@@ -29,4 +48,10 @@ internal class WebModuleRegistration
return (IWebModule) Feature.Plugin.Resolve(WebModuleType);
throw new ArtemisCoreException("WebModuleRegistration doesn't have a create function nor a web module type :(");
}
+
+ private void FeatureOnDisabled(object? sender, EventArgs e)
+ {
+ _webServerService.RemoveModule(this);
+ Feature.Disabled -= FeatureOnDisabled;
+ }
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/WebServer/WebServerService.cs b/src/Artemis.Core/Services/WebServer/WebServerService.cs
index e5030c9b4..263d95315 100644
--- a/src/Artemis.Core/Services/WebServer/WebServerService.cs
+++ b/src/Artemis.Core/Services/WebServer/WebServerService.cs
@@ -39,9 +39,9 @@ internal class WebServerService : IWebServerService, IDisposable
PluginsModule = new PluginsModule("/plugins");
if (coreService.IsInitialized)
- StartWebServer();
+ AutoStartWebServer();
else
- coreService.Initialized += (_, _) => StartWebServer();
+ coreService.Initialized += (sender, args) => AutoStartWebServer();
}
public event EventHandler? WebServerStopped;
@@ -138,7 +138,7 @@ internal class WebServerService : IWebServerService, IDisposable
// Add registered controllers to the API module
foreach (WebApiControllerRegistration registration in _controllers)
apiModule.RegisterController(registration.ControllerType, (Func) registration.UntypedFactory);
-
+
// Listen for state changes.
server.StateChanged += (s, e) => _logger.Verbose("WebServer new state - {state}", e.NewState);
@@ -173,6 +173,18 @@ internal class WebServerService : IWebServerService, IDisposable
OnWebServerStarted();
}
}
+
+ private void AutoStartWebServer()
+ {
+ try
+ {
+ StartWebServer();
+ }
+ catch (Exception exception)
+ {
+ _logger.Warning(exception, "Failed to initially start webserver");
+ }
+ }
#endregion
@@ -237,10 +249,6 @@ internal class WebServerService : IWebServerService, IDisposable
return endPoint;
}
- private void HandleDataModelRequest(Module module, T value) where T : DataModel, new()
- {
- }
-
public void RemovePluginEndPoint(PluginEndPoint endPoint)
{
PluginsModule.RemovePluginEndPoint(endPoint);
@@ -250,15 +258,20 @@ internal class WebServerService : IWebServerService, IDisposable
#region Controller management
- public void AddController(PluginFeature feature) where T : WebApiController
+ public WebApiControllerRegistration AddController(PluginFeature feature) where T : WebApiController
{
- _controllers.Add(new WebApiControllerRegistration(feature));
+ if (feature == null) throw new ArgumentNullException(nameof(feature));
+
+ WebApiControllerRegistration registration = new(this, feature);
+ _controllers.Add(registration);
StartWebServer();
+
+ return registration;
}
- public void RemoveController() where T : WebApiController
+ public void RemoveController(WebApiControllerRegistration registration)
{
- _controllers.RemoveAll(r => r.ControllerType == typeof(T));
+ _controllers.Remove(registration);
StartWebServer();
}
@@ -266,33 +279,31 @@ internal class WebServerService : IWebServerService, IDisposable
#region Module management
- public void AddModule(PluginFeature feature, Func create)
+ public WebModuleRegistration AddModule(PluginFeature feature, Func create)
{
if (feature == null) throw new ArgumentNullException(nameof(feature));
- _modules.Add(new WebModuleRegistration(feature, create));
+ WebModuleRegistration registration = new(this, feature, create);
+ _modules.Add(registration);
StartWebServer();
+
+ return registration;
}
- public void RemoveModule(Func create)
- {
- _modules.RemoveAll(r => r.Create == create);
- StartWebServer();
- }
-
- public void AddModule(PluginFeature feature) where T : IWebModule
+ public WebModuleRegistration AddModule(PluginFeature feature) where T : IWebModule
{
if (feature == null) throw new ArgumentNullException(nameof(feature));
- if (_modules.Any(r => r.WebModuleType == typeof(T)))
- return;
- _modules.Add(new WebModuleRegistration(feature, typeof(T)));
+ WebModuleRegistration registration = new(this, feature, typeof(T));
+ _modules.Add(registration);
StartWebServer();
+
+ return registration;
}
- public void RemoveModule() where T : IWebModule
+ public void RemoveModule(WebModuleRegistration registration)
{
- _modules.RemoveAll(r => r.WebModuleType == typeof(T));
+ _modules.Remove(registration);
StartWebServer();
}