fixed compatibility issue in .NET5/WebAssembly where assemblies were not being loaded into the default AppDomain, optimized service registration on WebAssembly, fixed spelling mistake for satellite assemblies constant and fixed issue in LocalizableComponent
This commit is contained in:
parent
15aa2c2e47
commit
b4b73b7e5a
|
@ -18,7 +18,7 @@ namespace Oqtane.Modules.Controls
|
||||||
{
|
{
|
||||||
if (!IsLocalizable)
|
if (!IsLocalizable)
|
||||||
{
|
{
|
||||||
return null;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = $"{ResourceKey}.{name}";
|
var key = $"{ResourceKey}.{name}";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Runtime.Loader;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
@ -64,30 +65,28 @@ namespace Oqtane.Client
|
||||||
|
|
||||||
await LoadClientAssemblies(httpClient);
|
await LoadClientAssemblies(httpClient);
|
||||||
|
|
||||||
// dynamically register module contexts and repository services
|
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
|
||||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
foreach (var assembly in assemblies)
|
||||||
foreach (Assembly assembly in assemblies)
|
|
||||||
{
|
{
|
||||||
var implementationTypes = assembly.GetTypes()
|
// dynamically register module services
|
||||||
.Where(item => item.GetInterfaces().Contains(typeof(IService)));
|
var implementationTypes = assembly.GetInterfaces<IService>();
|
||||||
|
foreach (var implementationType in implementationTypes)
|
||||||
foreach (Type implementationtype in implementationTypes)
|
|
||||||
{
|
{
|
||||||
Type servicetype = Type.GetType(implementationtype.AssemblyQualifiedName.Replace(implementationtype.Name, "I" + implementationtype.Name));
|
if (implementationType.AssemblyQualifiedName != null)
|
||||||
if (servicetype != null)
|
|
||||||
{
|
{
|
||||||
builder.Services.AddScoped(servicetype, implementationtype); // traditional service interface
|
var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, $"I{implementationType.Name}"));
|
||||||
}
|
builder.Services.AddScoped(serviceType ?? implementationType, implementationType);
|
||||||
else
|
|
||||||
{
|
|
||||||
builder.Services.AddScoped(implementationtype, implementationtype); // no interface defined for service
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assembly.GetInstances<IClientStartup>()
|
// register client startup services
|
||||||
.ToList()
|
var startUps = assembly.GetInstances<IClientStartup>();
|
||||||
.ForEach(x => x.ConfigureServices(builder.Services));
|
foreach (var startup in startUps)
|
||||||
|
{
|
||||||
|
startup.ConfigureServices(builder.Services);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var host = builder.Build();
|
var host = builder.Build();
|
||||||
|
|
||||||
ServiceActivator.Configure(host.Services);
|
ServiceActivator.Configure(host.Services);
|
||||||
|
@ -120,15 +119,7 @@ namespace Oqtane.Client
|
||||||
switch (Path.GetExtension(entry.Name))
|
switch (Path.GetExtension(entry.Name))
|
||||||
{
|
{
|
||||||
case ".dll":
|
case ".dll":
|
||||||
// Loads the stallite assemblies early
|
|
||||||
if (entry.Name.EndsWith(Constants.StalliteAssemblyExtension))
|
|
||||||
{
|
|
||||||
Assembly.Load(file);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dlls.Add(entry.Name, file);
|
dlls.Add(entry.Name, file);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ".pdb":
|
case ".pdb":
|
||||||
pdbs.Add(entry.Name, file);
|
pdbs.Add(entry.Name, file);
|
||||||
|
@ -142,11 +133,11 @@ namespace Oqtane.Client
|
||||||
{
|
{
|
||||||
if (pdbs.ContainsKey(item.Key))
|
if (pdbs.ContainsKey(item.Key))
|
||||||
{
|
{
|
||||||
Assembly.Load(item.Value, pdbs[item.Key]);
|
AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(item.Value), new MemoryStream(pdbs[item.Key]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assembly.Load(item.Value);
|
AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(item.Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@using System.Diagnostics.CodeAnalysis
|
@using System.Diagnostics.CodeAnalysis
|
||||||
@using System.Runtime.InteropServices
|
@using System.Runtime.InteropServices
|
||||||
@namespace Oqtane.UI
|
@namespace Oqtane.UI
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
|
@ -442,7 +442,7 @@
|
||||||
var paneindex = new Dictionary<string, int>();
|
var paneindex = new Dictionary<string, int>();
|
||||||
foreach (Module module in modules)
|
foreach (Module module in modules)
|
||||||
{
|
{
|
||||||
if (module.PageId == page.PageId || module.ModuleId == moduleid)
|
if ((module.PageId == page.PageId || module.ModuleId == moduleid) && module.ModuleDefinition != null)
|
||||||
{
|
{
|
||||||
var typename = string.Empty;
|
var typename = string.Empty;
|
||||||
if (module.ModuleDefinition != null && (module.ModuleDefinition.Runtimes == "" || module.ModuleDefinition.Runtimes.Contains(GetRuntime().ToString())))
|
if (module.ModuleDefinition != null && (module.ModuleDefinition.Runtimes == "" || module.ModuleDefinition.Runtimes.Contains(GetRuntime().ToString())))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -71,12 +71,12 @@ namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
if (_config.GetSection("Runtime").Value == "WebAssembly")
|
if (_config.GetSection("Runtime").Value == "WebAssembly")
|
||||||
{
|
{
|
||||||
// get list of assemblies which should be downloaded to browser
|
// get list of assemblies which should be downloaded to client
|
||||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
||||||
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
||||||
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
|
|
||||||
// Get the satellite assemblies
|
// insert satellite assemblies at beginning of list
|
||||||
foreach (var culture in _localizationManager.GetSupportedCultures())
|
foreach (var culture in _localizationManager.GetSupportedCultures())
|
||||||
{
|
{
|
||||||
var assembliesFolderPath = Path.Combine(binFolder, culture);
|
var assembliesFolderPath = Path.Combine(binFolder, culture);
|
||||||
|
@ -89,7 +89,7 @@ namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
foreach (var resourceFile in Directory.EnumerateFiles(assembliesFolderPath))
|
foreach (var resourceFile in Directory.EnumerateFiles(assembliesFolderPath))
|
||||||
{
|
{
|
||||||
list.Add(Path.Combine(culture, Path.GetFileNameWithoutExtension(resourceFile)));
|
list.Insert(0, Path.Combine(culture, Path.GetFileNameWithoutExtension(resourceFile)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -98,7 +98,7 @@ namespace Oqtane.Controllers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get module and theme dependencies
|
// insert module and theme dependencies at beginning of list
|
||||||
foreach (var assembly in assemblies)
|
foreach (var assembly in assemblies)
|
||||||
{
|
{
|
||||||
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModule))))
|
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModule))))
|
||||||
|
@ -106,7 +106,7 @@ namespace Oqtane.Controllers
|
||||||
var instance = Activator.CreateInstance(type) as IModule;
|
var instance = Activator.CreateInstance(type) as IModule;
|
||||||
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
if (!list.Contains(name)) list.Add(name);
|
if (!list.Contains(name)) list.Insert(0, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(ITheme))))
|
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(ITheme))))
|
||||||
|
@ -114,7 +114,7 @@ namespace Oqtane.Controllers
|
||||||
var instance = Activator.CreateInstance(type) as ITheme;
|
var instance = Activator.CreateInstance(type) as ITheme;
|
||||||
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
{
|
{
|
||||||
if (!list.Contains(name)) list.Add(name);
|
if (!list.Contains(name)) list.Insert(0, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -32,6 +32,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
}
|
}
|
||||||
|
|
||||||
var hostedServiceType = typeof(IHostedService);
|
var hostedServiceType = typeof(IHostedService);
|
||||||
|
|
||||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
|
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
|
||||||
foreach (var assembly in assemblies)
|
foreach (var assembly in assemblies)
|
||||||
{
|
{
|
||||||
|
@ -56,6 +57,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// register server startup services
|
||||||
var startUps = assembly.GetInstances<IServerStartup>();
|
var startUps = assembly.GetInstances<IServerStartup>();
|
||||||
foreach (var startup in startUps)
|
foreach (var startup in startUps)
|
||||||
{
|
{
|
||||||
|
@ -64,6 +66,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
|
|
||||||
if (runtime == Runtime.Server)
|
if (runtime == Runtime.Server)
|
||||||
{
|
{
|
||||||
|
// register client startup services if running on server
|
||||||
assembly.GetInstances<IClientStartup>()
|
assembly.GetInstances<IClientStartup>()
|
||||||
.ToList()
|
.ToList()
|
||||||
.ForEach(x => x.ConfigureServices(services));
|
.ForEach(x => x.ConfigureServices(services));
|
||||||
|
@ -143,7 +146,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
var assembliesFolder = new DirectoryInfo(Path.Combine(assemblyPath, culture));
|
var assembliesFolder = new DirectoryInfo(Path.Combine(assemblyPath, culture));
|
||||||
if (assembliesFolder.Exists)
|
if (assembliesFolder.Exists)
|
||||||
{
|
{
|
||||||
foreach (var assemblyFile in assembliesFolder.EnumerateFiles(Constants.StalliteAssemblyExtension))
|
foreach (var assemblyFile in assembliesFolder.EnumerateFiles(Constants.SatelliteAssemblyExtension))
|
||||||
{
|
{
|
||||||
AssemblyName assemblyName;
|
AssemblyName assemblyName;
|
||||||
try
|
try
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Oqtane.Modules;
|
using Oqtane.Modules;
|
||||||
|
@ -34,7 +34,6 @@ namespace System.Reflection
|
||||||
}
|
}
|
||||||
|
|
||||||
return assembly.GetTypes()
|
return assembly.GetTypes()
|
||||||
//.Where(t => t.GetInterfaces().Contains(interfaceType));
|
|
||||||
.Where(x => !x.IsInterface && !x.IsAbstract && interfaceType.IsAssignableFrom(x));
|
.Where(x => !x.IsInterface && !x.IsAbstract && interfaceType.IsAssignableFrom(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
namespace Oqtane.Shared {
|
namespace Oqtane.Shared {
|
||||||
|
@ -68,7 +68,7 @@ namespace Oqtane.Shared {
|
||||||
};
|
};
|
||||||
public static readonly string[] InvalidFileNameEndingChars = { ".", " " };
|
public static readonly string[] InvalidFileNameEndingChars = { ".", " " };
|
||||||
|
|
||||||
public static readonly string StalliteAssemblyExtension = ".resources.dll";
|
public static readonly string SatelliteAssemblyExtension = ".resources.dll";
|
||||||
|
|
||||||
public static readonly string DefaultCulture = CultureInfo.InstalledUICulture.Name;
|
public static readonly string DefaultCulture = CultureInfo.InstalledUICulture.Name;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user