diff --git a/Moonlight.Client/Interfaces/IAppLoader.cs b/Moonlight.Client/Interfaces/IAppLoader.cs deleted file mode 100644 index f1e2b5e0..00000000 --- a/Moonlight.Client/Interfaces/IAppLoader.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Moonlight.Client.Interfaces; - -public interface IAppLoader -{ - public int Priority { get; } - public Task Load(IServiceProvider serviceProvider); -} \ No newline at end of file diff --git a/Moonlight.Client/Interfaces/IAppScreen.cs b/Moonlight.Client/Interfaces/IAppScreen.cs deleted file mode 100644 index 2301a9f7..00000000 --- a/Moonlight.Client/Interfaces/IAppScreen.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Microsoft.AspNetCore.Components; - -namespace Moonlight.Client.Interfaces; - -public interface IAppScreen -{ - public int Priority { get; } - public Task ShouldRender(IServiceProvider serviceProvider); - public RenderFragment Render(); -} \ No newline at end of file diff --git a/Moonlight.Client/Interfaces/IAppStartup.cs b/Moonlight.Client/Interfaces/IAppStartup.cs deleted file mode 100644 index b8fcb443..00000000 --- a/Moonlight.Client/Interfaces/IAppStartup.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Microsoft.AspNetCore.Components.WebAssembly.Hosting; - -namespace Moonlight.Client.Interfaces; - -public interface IAppStartup -{ - public Task BuildApp(WebAssemblyHostBuilder builder); - public Task ConfigureApp(WebAssemblyHost app); -} \ No newline at end of file diff --git a/Moonlight.Client/Interfaces/IPluginStartup.cs b/Moonlight.Client/Interfaces/IPluginStartup.cs new file mode 100644 index 00000000..3d084ed1 --- /dev/null +++ b/Moonlight.Client/Interfaces/IPluginStartup.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; + +namespace Moonlight.Client.Interfaces; + +public interface IPluginStartup +{ + public Task BuildApplication(WebAssemblyHostBuilder builder); + public Task ConfigureApplication(WebAssemblyHost app); +} \ No newline at end of file diff --git a/Moonlight.Client/Startup.cs b/Moonlight.Client/Startup.cs index 1eb0f6f2..b782d82a 100644 --- a/Moonlight.Client/Startup.cs +++ b/Moonlight.Client/Startup.cs @@ -38,7 +38,7 @@ public class Startup private PluginLoaderService PluginLoaderService; private ApplicationAssemblyService ApplicationAssemblyService; - private IAppStartup[] PluginAppStartups; + private IPluginStartup[] PluginStartups; public async Task Run(string[] args, Assembly[]? assemblies = null) { @@ -182,8 +182,6 @@ public class Startup configuration.AddAssemblies(ApplicationAssemblyService.AdditionalAssemblies); configuration.AddAssemblies(ApplicationAssemblyService.PluginAssemblies); - configuration.AddInterface(); - configuration.AddInterface(); configuration.AddInterface(); }); @@ -226,25 +224,42 @@ public class Startup private Task InitializePlugins() { - var initialisationServiceCollection = new ServiceCollection(); + // Define minimal service collection + var startupSc = new ServiceCollection(); - initialisationServiceCollection.AddLogging(builder => { builder.AddProviders(LoggerProviders); }); - - // Configure plugin loading by using the interface service - initialisationServiceCollection.AddInterfaces(configuration => + // Create logging proxy + startupSc.AddLogging(builder => { - // We use moonlight itself as a plugin assembly - configuration.AddAssembly(typeof(Startup).Assembly); - - configuration.AddAssemblies(ApplicationAssemblyService.AdditionalAssemblies); - configuration.AddAssemblies(ApplicationAssemblyService.PluginAssemblies); - - configuration.AddInterface(); + builder.ClearProviders(); + builder.AddProviders(LoggerProviders); }); - var initialisationServiceProvider = initialisationServiceCollection.BuildServiceProvider(); + // + var startupSp = startupSc.BuildServiceProvider(); + + // Initialize plugin startups + var startups = new List(); + var startupType = typeof(IPluginStartup); - PluginAppStartups = initialisationServiceProvider.GetRequiredService(); + foreach (var pluginAssembly in ApplicationAssemblyService.PluginAssemblies) + { + var startupTypes = pluginAssembly + .ExportedTypes + .Where(x => x.IsAbstract && x.IsInterface && x.IsAssignableTo(startupType)) + .ToArray(); + + foreach (var type in startupTypes) + { + var startup = ActivatorUtilities.CreateInstance(startupSp, type) as IPluginStartup; + + if(startup == null) + continue; + + startups.Add(startup); + } + } + + PluginStartups = startups.ToArray(); return Task.CompletedTask; } @@ -253,11 +268,11 @@ public class Startup private async Task HookPluginBuild() { - foreach (var pluginAppStartup in PluginAppStartups) + foreach (var pluginAppStartup in PluginStartups) { try { - await pluginAppStartup.BuildApp(WebAssemblyHostBuilder); + await pluginAppStartup.BuildApplication(WebAssemblyHostBuilder); } catch (Exception e) { @@ -272,11 +287,11 @@ public class Startup private async Task HookPluginConfigure() { - foreach (var pluginAppStartup in PluginAppStartups) + foreach (var pluginAppStartup in PluginStartups) { try { - await pluginAppStartup.ConfigureApp(WebAssemblyHost); + await pluginAppStartup.ConfigureApplication(WebAssemblyHost); } catch (Exception e) { diff --git a/Moonlight.Client/UI/Layouts/MainLayout.razor b/Moonlight.Client/UI/Layouts/MainLayout.razor index 46c4c2f4..68596518 100644 --- a/Moonlight.Client/UI/Layouts/MainLayout.razor +++ b/Moonlight.Client/UI/Layouts/MainLayout.razor @@ -9,8 +9,6 @@ @inject IServiceProvider ServiceProvider @inject ILogger Logger -@inject IAppLoader[] AppLoaders -@inject IAppScreen[] AppScreens @inject FrontendConfiguration Configuration @Configuration.Title @@ -83,58 +81,8 @@ else IsLoading = true; await InvokeAsync(StateHasChanged); - // - await RunLoaders(); - - // Screens - await RenderScreens(); - // IsLoading = false; await InvokeAsync(StateHasChanged); } - - private async Task RunLoaders() - { - var appLoaders = AppLoaders - .OrderBy(x => x.Priority); - - foreach (var loader in appLoaders) //TODO: Measure performance of every loader? - { - try - { - Logger.LogDebug("Running application loader '{name}'", loader.GetType().Name); - await loader.Load(ServiceProvider); - } - catch (HttpApiException) - { - throw; - } - catch (Exception e) - { - Logger.LogCritical("An app loader threw an unhandled exception: {e}", e); - } - } - } - - public async Task RenderScreens() - { - CurrentScreen = null; - - var appScreens = AppScreens - .OrderBy(x => x.Priority); - - foreach (var screen in appScreens) - { - if (!await screen.ShouldRender(ServiceProvider)) - continue; - - CurrentScreen = screen.Render(); - - await InvokeAsync(StateHasChanged); - return; - } - - await InvokeAsync(StateHasChanged); - } } \ No newline at end of file