From 2e2d46996ade6991431a1125b597ecb02ac23a33 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 30 Sep 2020 00:07:00 +0300 Subject: [PATCH] Refactoring --- .../Controllers/InstallationController.cs | 7 +-- .../ApplicationBuilderExtensions.cs | 48 +++++++----------- .../OqtaneServiceCollectionExtensions.cs | 49 ++++++++++--------- .../Interfaces/ILocalizationManager.cs | 9 ++++ .../Localization/LocalizationOptions.cs | 9 ++++ .../Localization/LocalizationSettings.cs | 18 ------- .../Infrastructure/LocalizationManager.cs | 29 +++++++++++ Oqtane.Server/Startup.cs | 6 +++ .../Extensions/EnumerableExtensions.cs | 8 +++ Oqtane.Shared/Shared/ServiceActivator.cs | 22 +++++++++ 10 files changed, 130 insertions(+), 75 deletions(-) create mode 100644 Oqtane.Server/Infrastructure/Interfaces/ILocalizationManager.cs create mode 100644 Oqtane.Server/Infrastructure/Localization/LocalizationOptions.cs delete mode 100644 Oqtane.Server/Infrastructure/Localization/LocalizationSettings.cs create mode 100644 Oqtane.Server/Infrastructure/LocalizationManager.cs create mode 100644 Oqtane.Shared/Extensions/EnumerableExtensions.cs create mode 100644 Oqtane.Shared/Shared/ServiceActivator.cs diff --git a/Oqtane.Server/Controllers/InstallationController.cs b/Oqtane.Server/Controllers/InstallationController.cs index 06c3fb48..d3529a98 100644 --- a/Oqtane.Server/Controllers/InstallationController.cs +++ b/Oqtane.Server/Controllers/InstallationController.cs @@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Oqtane.Infrastructure; -using Oqtane.Infrastructure.Localization; using Oqtane.Models; using Oqtane.Modules; using Oqtane.Shared; @@ -21,12 +20,14 @@ namespace Oqtane.Controllers private readonly IConfigurationRoot _config; private readonly IInstallationManager _installationManager; private readonly IDatabaseManager _databaseManager; + private readonly ILocalizationManager _localizationManager; - public InstallationController(IConfigurationRoot config, IInstallationManager installationManager, IDatabaseManager databaseManager) + public InstallationController(IConfigurationRoot config, IInstallationManager installationManager, IDatabaseManager databaseManager, ILocalizationManager localizationManager) { _config = config; _installationManager = installationManager; _databaseManager = databaseManager; + _localizationManager = localizationManager; } // POST api/ @@ -76,7 +77,7 @@ namespace Oqtane.Controllers var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); // Get the satellite assemblies - foreach (var culture in LocalizationSettings.SupportedCultures) + foreach (var culture in _localizationManager.GetSupportedCultures()) { if (culture == Constants.DefaultCulture) { diff --git a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs index 476d8bee..67676d16 100644 --- a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs +++ b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs @@ -4,44 +4,13 @@ using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Oqtane.Infrastructure; -using Oqtane.Infrastructure.Localization; namespace Oqtane.Extensions { public static class ApplicationBuilderExtensions { - private static readonly string DefaultCultureKey = "Localization:DefaultCulture"; - private static readonly string SupportedCulturesKey = "Localization:SupportedCultures"; - - public static IApplicationBuilder UseOqtaneLocalization(this IApplicationBuilder app) - { - var configuration = app.ApplicationServices.GetService(); - var defaultCulture = configuration.GetSection(DefaultCultureKey).Value; - var supportedCultures = configuration.GetSection(SupportedCulturesKey).Get(); - if (defaultCulture == CultureInfo.InstalledUICulture.Name) - { - LocalizationSettings.DefaultCulture = defaultCulture; - } - - if (supportedCultures.Length > 0) - { - LocalizationSettings.SupportedCultures.AddRange(supportedCultures); - } - - CultureInfo.CurrentUICulture = new CultureInfo(defaultCulture); - - app.UseRequestLocalization(options => { - options.SetDefaultCulture(defaultCulture) - .AddSupportedUICultures(supportedCultures) - .AddSupportedUICultures(supportedCultures); - }); - - return app; - } - public static IApplicationBuilder ConfigureOqtaneAssemblies(this IApplicationBuilder app, IWebHostEnvironment env) { var startUps = AppDomain.CurrentDomain @@ -55,5 +24,22 @@ namespace Oqtane.Extensions return app; } + + public static IApplicationBuilder UseOqtaneLocalization(this IApplicationBuilder app) + { + var localizationManager = app.ApplicationServices.GetService(); + var defaultCulture = localizationManager.GetDefaultCulture(); + var supportedCultures = localizationManager.GetSupportedCultures(); + + CultureInfo.CurrentUICulture = new CultureInfo(defaultCulture); + + app.UseRequestLocalization(options => { + options.SetDefaultCulture(defaultCulture) + .AddSupportedUICultures(supportedCultures) + .AddSupportedUICultures(supportedCultures); + }); + + return app; + } } } diff --git a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs index 09776f45..4090be8d 100644 --- a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs +++ b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs @@ -5,7 +5,6 @@ using System.Reflection; using System.Runtime.Loader; using Microsoft.Extensions.Hosting; using Oqtane.Infrastructure; -using Oqtane.Infrastructure.Localization; using Oqtane.Modules; using Oqtane.Services; using Oqtane.Shared; @@ -134,35 +133,39 @@ namespace Microsoft.Extensions.DependencyInjection AssemblyLoadContext.Default.Resolving += ResolveDependencies; - foreach (var culture in LocalizationSettings.SupportedCultures) + using (var serviceScope = ServiceActivator.GetScope()) { - if (culture == Constants.DefaultCulture) + var localizationManager = serviceScope.ServiceProvider.GetService(); + foreach (var culture in localizationManager.GetSupportedCultures()) { - continue; - } - - var assembliesFolder = new DirectoryInfo(Path.Combine(assemblyPath, culture)); - foreach (var assemblyFile in assembliesFolder.EnumerateFiles(Constants.StalliteAssemblyExtension)) - { - AssemblyName assemblyName; - try + if (culture == Constants.DefaultCulture) { - assemblyName = AssemblyName.GetAssemblyName(assemblyFile.FullName); - } - catch - { - Console.WriteLine($"Not Satellite Assembly : {assemblyFile.Name}"); continue; } - try + var assembliesFolder = new DirectoryInfo(Path.Combine(assemblyPath, culture)); + foreach (var assemblyFile in assembliesFolder.EnumerateFiles(Constants.StalliteAssemblyExtension)) { - Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(assemblyFile.FullName))); - Console.WriteLine($"Loaded : {assemblyName}"); - } - catch (Exception e) - { - Console.WriteLine($"Failed : {assemblyName}\n{e}"); + AssemblyName assemblyName; + try + { + assemblyName = AssemblyName.GetAssemblyName(assemblyFile.FullName); + } + catch + { + Console.WriteLine($"Not Satellite Assembly : {assemblyFile.Name}"); + continue; + } + + try + { + Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(assemblyFile.FullName))); + Console.WriteLine($"Loaded : {assemblyName}"); + } + catch (Exception e) + { + Console.WriteLine($"Failed : {assemblyName}\n{e}"); + } } } } diff --git a/Oqtane.Server/Infrastructure/Interfaces/ILocalizationManager.cs b/Oqtane.Server/Infrastructure/Interfaces/ILocalizationManager.cs new file mode 100644 index 00000000..fa20eef4 --- /dev/null +++ b/Oqtane.Server/Infrastructure/Interfaces/ILocalizationManager.cs @@ -0,0 +1,9 @@ +namespace Oqtane.Infrastructure +{ + public interface ILocalizationManager + { + string GetDefaultCulture(); + + string[] GetSupportedCultures(); + } +} diff --git a/Oqtane.Server/Infrastructure/Localization/LocalizationOptions.cs b/Oqtane.Server/Infrastructure/Localization/LocalizationOptions.cs new file mode 100644 index 00000000..6330130e --- /dev/null +++ b/Oqtane.Server/Infrastructure/Localization/LocalizationOptions.cs @@ -0,0 +1,9 @@ +namespace Oqtane.Infrastructure +{ + public class LocalizationOptions + { + public string DefaultCulture { get; set; } + + public string[] SupportedCultures { get; set; } + } +} diff --git a/Oqtane.Server/Infrastructure/Localization/LocalizationSettings.cs b/Oqtane.Server/Infrastructure/Localization/LocalizationSettings.cs deleted file mode 100644 index 38f74295..00000000 --- a/Oqtane.Server/Infrastructure/Localization/LocalizationSettings.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; -using Oqtane.Shared; - -namespace Oqtane.Infrastructure.Localization -{ - public static class LocalizationSettings - { - static LocalizationSettings() - { - DefaultCulture = Constants.DefaultCulture; - SupportedCultures = new List { DefaultCulture }; - } - - public static string DefaultCulture { get; set; } - - public static List SupportedCultures { get; } - } -} diff --git a/Oqtane.Server/Infrastructure/LocalizationManager.cs b/Oqtane.Server/Infrastructure/LocalizationManager.cs new file mode 100644 index 00000000..22b4ca79 --- /dev/null +++ b/Oqtane.Server/Infrastructure/LocalizationManager.cs @@ -0,0 +1,29 @@ +using System.Collections; +using Microsoft.Extensions.Options; +using Oqtane.Shared; + +namespace Oqtane.Infrastructure +{ + public class LocalizationManager : ILocalizationManager + { + private static readonly string DefaultCulture = Constants.DefaultCulture; + private static readonly string[] SupportedCultures = new[] { DefaultCulture }; + + private readonly LocalizationOptions _localizationOptions; + + public LocalizationManager(IOptions localizationOptions) + { + _localizationOptions = localizationOptions.Value; + } + + public string GetDefaultCulture() + => string.IsNullOrEmpty(_localizationOptions.DefaultCulture) + ? DefaultCulture + : _localizationOptions.DefaultCulture; + + public string[] GetSupportedCultures() + => _localizationOptions.SupportedCultures.IsNullOrEmpty() + ? SupportedCultures + : _localizationOptions.SupportedCultures; + } +} diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index 256d44a3..98d43bcd 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -128,6 +128,8 @@ namespace Oqtane .AddSignInManager() .AddDefaultTokenProviders(); + services.Configure(Configuration.GetSection("Localization")); + services.Configure(options => { // Password settings @@ -190,6 +192,7 @@ namespace Oqtane services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -199,6 +202,9 @@ namespace Oqtane services.AddTransient(); services.AddTransient(); + // TODO: Check if there's a better way instead of building service provider + ServiceActivator.Configure(services.BuildServiceProvider()); + // load the external assemblies into the app domain, install services services.AddOqtane(_runtime); diff --git a/Oqtane.Shared/Extensions/EnumerableExtensions.cs b/Oqtane.Shared/Extensions/EnumerableExtensions.cs new file mode 100644 index 00000000..a4bdde7c --- /dev/null +++ b/Oqtane.Shared/Extensions/EnumerableExtensions.cs @@ -0,0 +1,8 @@ +namespace System.Collections +{ + public static class EnumerableExtensions + { + public static bool IsNullOrEmpty(this IEnumerable source) + => source == null || source.GetEnumerator().MoveNext() == false; + } +} diff --git a/Oqtane.Shared/Shared/ServiceActivator.cs b/Oqtane.Shared/Shared/ServiceActivator.cs new file mode 100644 index 00000000..5718d174 --- /dev/null +++ b/Oqtane.Shared/Shared/ServiceActivator.cs @@ -0,0 +1,22 @@ +using System; +using Microsoft.Extensions.DependencyInjection; + +namespace Oqtane.Shared +{ + public static class ServiceActivator + { + private static IServiceProvider _serviceProvider = null; + + public static void Configure(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public static IServiceScope GetScope(IServiceProvider serviceProvider = null) + { + var provider = serviceProvider ?? _serviceProvider; + + return provider?.GetRequiredService().CreateScope(); + } + } +}