diff --git a/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs new file mode 100644 index 00000000..e06b991e --- /dev/null +++ b/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs @@ -0,0 +1,52 @@ +using Microsoft.AspNetCore.Components.Authorization; +using Oqtane.Providers; +using Oqtane.Services; +using Oqtane.Shared; + +namespace Microsoft.Extensions.DependencyInjection +{ + public static class OqtaneServiceCollectionExtensions + { + public static IServiceCollection AddOqtaneAuthorization(this IServiceCollection services) + { + services.AddAuthorizationCore(); + services.AddScoped(); + services.AddScoped(s => s.GetRequiredService()); + + return services; + } + + internal static IServiceCollection AddOqtaneScopedServices(this IServiceCollection services) + { + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + return services; + } + } +} diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index fdc5145f..184ff75d 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -8,14 +8,12 @@ using System.Net.Http; using System.Reflection; using System.Runtime.Loader; using System.Threading.Tasks; -using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.DependencyInjection; using Microsoft.JSInterop; using Oqtane.Interfaces; using Oqtane.Modules; -using Oqtane.Providers; using Oqtane.Services; using Oqtane.Shared; using Oqtane.UI; @@ -28,7 +26,8 @@ namespace Oqtane.Client { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add("app"); - HttpClient httpClient = new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)}; + + var httpClient = new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)}; builder.Services.AddSingleton(httpClient); builder.Services.AddOptions(); @@ -37,38 +36,10 @@ namespace Oqtane.Client builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); // register auth services - builder.Services.AddAuthorizationCore(); - builder.Services.AddScoped(); - builder.Services.AddScoped(s => s.GetRequiredService()); + builder.Services.AddOqtaneAuthorization(); // register scoped core services - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); + builder.Services.AddOqtaneScopedServices(); await LoadClientAssemblies(httpClient); @@ -76,49 +47,18 @@ namespace Oqtane.Client foreach (var assembly in assemblies) { // dynamically register module services - var implementationTypes = assembly.GetInterfaces(); - foreach (var implementationType in implementationTypes) - { - if (implementationType.AssemblyQualifiedName != null) - { - var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, $"I{implementationType.Name}")); - builder.Services.AddScoped(serviceType ?? implementationType, implementationType); - } - } + RegisterModuleServices(assembly, builder.Services); // dynamically register database providers - var databaseTypes = assembly.GetInterfaces(); - foreach (var databaseType in databaseTypes) - { - if (databaseType.AssemblyQualifiedName != null) - { - var serviceType = Type.GetType("Oqtane.Interfaces.IDatabase, Oqtane.Shared"); - builder.Services.AddScoped(serviceType ?? databaseType, databaseType); - } - } + RegisterDatabaseProviders(assembly, builder.Services); // register client startup services - var startUps = assembly.GetInstances(); - foreach (var startup in startUps) - { - startup.ConfigureServices(builder.Services); - } + RegisterClientStartups(assembly, builder.Services); } var host = builder.Build(); - var jsRuntime = host.Services.GetRequiredService(); - var interop = new Interop(jsRuntime); - var localizationCookie = await interop.GetCookie(CookieRequestCultureProvider.DefaultCookieName); - var culture = CookieRequestCultureProvider.ParseCookieValue(localizationCookie).UICultures[0].Value; - var localizationService = host.Services.GetRequiredService(); - var cultures = await localizationService.GetCulturesAsync(); - if (culture == null || !cultures.Any(c => c.Name.Equals(culture, StringComparison.OrdinalIgnoreCase))) - { - culture = cultures.Single(c => c.IsDefault).Name; - } - - SetCulture(culture); + await SetCultureFromLocalizationCookie(host.Services); ServiceActivator.Configure(host.Services); @@ -174,6 +114,58 @@ namespace Oqtane.Client } } + private static void RegisterModuleServices(Assembly assembly, IServiceCollection services) + { + var implementationTypes = assembly.GetInterfaces(); + foreach (var implementationType in implementationTypes) + { + if (implementationType.AssemblyQualifiedName != null) + { + var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, $"I{implementationType.Name}")); + services.AddScoped(serviceType ?? implementationType, implementationType); + } + } + } + + private static void RegisterDatabaseProviders(Assembly assembly, IServiceCollection services) + { + var databaseTypes = assembly.GetInterfaces(); + foreach (var databaseType in databaseTypes) + { + if (databaseType.AssemblyQualifiedName != null) + { + var serviceType = Type.GetType("Oqtane.Interfaces.IDatabase, Oqtane.Shared"); + services.AddScoped(serviceType ?? databaseType, databaseType); + } + } + } + + private static void RegisterClientStartups(Assembly assembly, IServiceCollection services) + { + var startUps = assembly.GetInstances(); + foreach (var startup in startUps) + { + startup.ConfigureServices(services); + } + } + + private static async Task SetCultureFromLocalizationCookie(IServiceProvider serviceProvider) + { + var jsRuntime = serviceProvider.GetRequiredService(); + var interop = new Interop(jsRuntime); + var localizationCookie = await interop.GetCookie(CookieRequestCultureProvider.DefaultCookieName); + var culture = CookieRequestCultureProvider.ParseCookieValue(localizationCookie).UICultures[0].Value; + var localizationService = serviceProvider.GetRequiredService(); + var cultures = await localizationService.GetCulturesAsync(); + + if (culture == null || !cultures.Any(c => c.Name.Equals(culture, StringComparison.OrdinalIgnoreCase))) + { + culture = cultures.Single(c => c.IsDefault).Name; + } + + SetCulture(culture); + } + private static void SetCulture(string culture) { var cultureInfo = CultureInfo.GetCultureInfo(culture); diff --git a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs index 432d01c3..6dd5186e 100644 --- a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs +++ b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs @@ -19,7 +19,6 @@ using Oqtane.Security; using Oqtane.Services; using Oqtane.Shared; -// ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection { public static class OqtaneServiceCollectionExtensions