optimize satellite assembly loading based on the new model where all cultures are available

This commit is contained in:
Shaun Walker
2022-07-21 16:02:23 -04:00
parent d05fba06ec
commit 6bfab696ad
5 changed files with 47 additions and 72 deletions

View File

@ -32,7 +32,7 @@ else
<select id="_code" class="form-select" @bind="@_code" required> <select id="_code" class="form-select" @bind="@_code" required>
@foreach (var culture in _availableCultures) @foreach (var culture in _availableCultures)
{ {
<option value="@culture.Name">@culture.DisplayName</option> <option value="@culture.Name">@(culture.DisplayName + " (" + culture.Name + ")")</option>
} }
</select> </select>
</div> </div>
@ -161,33 +161,32 @@ else
} }
@code { @code {
private ElementReference form; private ElementReference form;
private bool validated = false; private bool validated = false;
private string _code = string.Empty; private string _code = string.Empty;
private string _isDefault = "False"; private string _isDefault = "False";
private string _message; private string _message;
private IEnumerable<Culture> _supportedCultures; private IEnumerable<Culture> _supportedCultures;
private IEnumerable<Culture> _availableCultures; private IEnumerable<Culture> _availableCultures;
private List<Package> _packages; private List<Package> _packages;
private string _price = "free"; private string _price = "free";
private string _search = ""; private string _search = "";
private string _productname = ""; private string _productname = "";
private string _license = ""; private string _license = "";
private string _packageid = ""; private string _packageid = "";
private string _version = ""; private string _version = "";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
var languages = await LanguageService.GetLanguagesAsync(PageState.Site.SiteId); var languages = await LanguageService.GetLanguagesAsync(PageState.Site.SiteId);
var languagesCodes = languages.Select(l => l.Code).ToList(); var languagesCodes = languages.Select(l => l.Code).ToList();
_supportedCultures = await LocalizationService.GetCulturesAsync(); _supportedCultures = await LocalizationService.GetCulturesAsync();
_availableCultures = _supportedCultures _availableCultures = _supportedCultures.Where(c => !c.Name.Equals(Constants.DefaultCulture) && !languagesCodes.Contains(c.Name));
.Where(c => !c.Name.Equals(Constants.DefaultCulture) && !languagesCodes.Contains(c.Name)); await LoadTranslations();
await LoadTranslations();
if (_supportedCultures.Count() == 1) if (_supportedCultures.Count() == 1)
{ {

View File

@ -12,6 +12,7 @@ using Oqtane.Shared;
using System.Linq; using System.Linq;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System;
namespace Oqtane.Controllers namespace Oqtane.Controllers
{ {
@ -42,7 +43,7 @@ namespace Oqtane.Controllers
packagename = "Oqtane"; packagename = "Oqtane";
} }
var languages = _languages.GetLanguages(SiteId).ToList(); var languages = _languages.GetLanguages(SiteId).ToList();
foreach (var file in Directory.EnumerateFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), packagename + ".Client.resources.dll", SearchOption.AllDirectories)) foreach (var file in Directory.EnumerateFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), $"{packagename}.*{Constants.SatelliteAssemblyExtension}", SearchOption.AllDirectories))
{ {
var code = Path.GetFileName(Path.GetDirectoryName(file)); var code = Path.GetFileName(Path.GetDirectoryName(file));
if (languages.Any(item => item.Code == code)) if (languages.Any(item => item.Code == code))

View File

@ -22,11 +22,15 @@ namespace Oqtane.Controllers
// GET: api/localization // GET: api/localization
[HttpGet()] [HttpGet()]
public IEnumerable<Culture> Get() public IEnumerable<Culture> Get()
=> _localizationManager.GetSupportedCultures().Select(c => new Culture { {
Name = CultureInfo.GetCultureInfo(c).Name, var cultures = _localizationManager.GetSupportedCultures().Select(c => new Culture
DisplayName = CultureInfo.GetCultureInfo(c).DisplayName, {
IsDefault = _localizationManager.GetDefaultCulture() Name = CultureInfo.GetCultureInfo(c).Name,
DisplayName = CultureInfo.GetCultureInfo(c).DisplayName,
IsDefault = _localizationManager.GetDefaultCulture()
.Equals(CultureInfo.GetCultureInfo(c).Name, StringComparison.OrdinalIgnoreCase) .Equals(CultureInfo.GetCultureInfo(c).Name, StringComparison.OrdinalIgnoreCase)
}); });
return cultures.OrderBy(item => item.DisplayName);
}
} }
} }

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Reflection.Metadata;
using System.Runtime.Loader; using System.Runtime.Loader;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.OAuth; using Microsoft.AspNetCore.Authentication.OAuth;
@ -17,6 +18,7 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Oqtane.Infrastructure; using Oqtane.Infrastructure;
using Oqtane.Models;
using Oqtane.Modules; using Oqtane.Modules;
using Oqtane.Repository; using Oqtane.Repository;
using Oqtane.Security; using Oqtane.Security;
@ -315,52 +317,26 @@ namespace Microsoft.Extensions.DependencyInjection
private static void LoadSatelliteAssemblies(string[] supportedCultures) private static void LoadSatelliteAssemblies(string[] supportedCultures)
{ {
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
if (assemblyPath == null)
{
return;
}
AssemblyLoadContext.Default.Resolving += ResolveDependencies; AssemblyLoadContext.Default.Resolving += ResolveDependencies;
foreach (var culture in supportedCultures) foreach (var file in Directory.EnumerateFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), $"*{Constants.SatelliteAssemblyExtension}", SearchOption.AllDirectories))
{ {
if (culture == Constants.DefaultCulture) var code = Path.GetFileName(Path.GetDirectoryName(file));
if (supportedCultures.Contains(code))
{ {
continue; try
}
var assembliesFolder = new DirectoryInfo(Path.Combine(assemblyPath, culture));
if (assembliesFolder.Exists)
{
foreach (var assemblyFile in assembliesFolder.EnumerateFiles($"*{Constants.SatelliteAssemblyExtension}"))
{ {
AssemblyName assemblyName; Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(System.IO.File.ReadAllBytes(file)));
try Debug.WriteLine($"Oqtane Info: Loaded Satellite Assembly {file}");
{ }
assemblyName = AssemblyName.GetAssemblyName(assemblyFile.FullName); catch (Exception ex)
} {
catch Debug.WriteLine($"Oqtane Error: Unable To Load Satellite Assembly {file} - {ex}");
{
Debug.WriteLine($"Oqtane Error: Cannot Get Satellite Assembly Name For {assemblyFile.Name}");
continue;
}
try
{
Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(System.IO.File.ReadAllBytes(assemblyFile.FullName)));
Debug.WriteLine($"Oqtane Info: Loaded Assembly {assemblyName}");
}
catch (Exception ex)
{
Debug.WriteLine($"Oqtane Error: Unable To Load Assembly {assemblyName} - {ex}");
}
} }
} }
else else
{ {
Debug.WriteLine($"Oqtane Error: The Satellite Assembly Folder For {culture} Does Not Exist"); Debug.WriteLine($"Oqtane Error: Culture Not Supported For Satellite Assembly {file}");
} }
} }
} }

View File

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Oqtane.Shared; using Oqtane.Shared;
@ -12,7 +8,6 @@ namespace Oqtane.Infrastructure
public class LocalizationManager : ILocalizationManager public class LocalizationManager : ILocalizationManager
{ {
private static readonly string DefaultCulture = Constants.DefaultCulture; private static readonly string DefaultCulture = Constants.DefaultCulture;
private static readonly string[] DefaultSupportedCultures = new[] { DefaultCulture };
private readonly LocalizationOptions _localizationOptions; private readonly LocalizationOptions _localizationOptions;