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:
Shaun Walker 2020-11-03 14:41:49 -05:00
parent 15aa2c2e47
commit b4b73b7e5a
7 changed files with 38 additions and 45 deletions

View File

@ -18,7 +18,7 @@ namespace Oqtane.Modules.Controls
{
if (!IsLocalizable)
{
return null;
return name;
}
var key = $"{ResourceKey}.{name}";

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
@ -6,6 +6,7 @@ using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using System.Runtime.Loader;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
@ -64,30 +65,28 @@ namespace Oqtane.Client
await LoadClientAssemblies(httpClient);
// dynamically register module contexts and repository services
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
foreach (var assembly in assemblies)
{
var implementationTypes = assembly.GetTypes()
.Where(item => item.GetInterfaces().Contains(typeof(IService)));
foreach (Type implementationtype in implementationTypes)
// dynamically register module services
var implementationTypes = assembly.GetInterfaces<IService>();
foreach (var implementationType in implementationTypes)
{
Type servicetype = Type.GetType(implementationtype.AssemblyQualifiedName.Replace(implementationtype.Name, "I" + implementationtype.Name));
if (servicetype != null)
if (implementationType.AssemblyQualifiedName != null)
{
builder.Services.AddScoped(servicetype, implementationtype); // traditional service interface
}
else
{
builder.Services.AddScoped(implementationtype, implementationtype); // no interface defined for service
var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, $"I{implementationType.Name}"));
builder.Services.AddScoped(serviceType ?? implementationType, implementationType);
}
}
assembly.GetInstances<IClientStartup>()
.ToList()
.ForEach(x => x.ConfigureServices(builder.Services));
// register client startup services
var startUps = assembly.GetInstances<IClientStartup>();
foreach (var startup in startUps)
{
startup.ConfigureServices(builder.Services);
}
}
var host = builder.Build();
ServiceActivator.Configure(host.Services);
@ -120,15 +119,7 @@ namespace Oqtane.Client
switch (Path.GetExtension(entry.Name))
{
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;
case ".pdb":
pdbs.Add(entry.Name, file);
@ -142,11 +133,11 @@ namespace Oqtane.Client
{
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
{
Assembly.Load(item.Value);
AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(item.Value));
}
}
}

View File

@ -1,4 +1,4 @@
@using System.Diagnostics.CodeAnalysis
@using System.Diagnostics.CodeAnalysis
@using System.Runtime.InteropServices
@namespace Oqtane.UI
@inject AuthenticationStateProvider AuthenticationStateProvider
@ -442,7 +442,7 @@
var paneindex = new Dictionary<string, int>();
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;
if (module.ModuleDefinition != null && (module.ModuleDefinition.Runtimes == "" || module.ModuleDefinition.Runtimes.Contains(GetRuntime().ToString())))

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using System.Reflection;
using System.Linq;
@ -71,12 +71,12 @@ namespace Oqtane.Controllers
{
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 list = assemblies.Select(a => a.GetName().Name).ToList();
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
// Get the satellite assemblies
// insert satellite assemblies at beginning of list
foreach (var culture in _localizationManager.GetSupportedCultures())
{
var assembliesFolderPath = Path.Combine(binFolder, culture);
@ -89,7 +89,7 @@ namespace Oqtane.Controllers
{
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
@ -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 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;
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))))
@ -114,7 +114,7 @@ namespace Oqtane.Controllers
var instance = Activator.CreateInstance(type) as ITheme;
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);
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
@ -32,6 +32,7 @@ namespace Microsoft.Extensions.DependencyInjection
}
var hostedServiceType = typeof(IHostedService);
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
foreach (var assembly in assemblies)
{
@ -56,6 +57,7 @@ namespace Microsoft.Extensions.DependencyInjection
}
}
// register server startup services
var startUps = assembly.GetInstances<IServerStartup>();
foreach (var startup in startUps)
{
@ -64,6 +66,7 @@ namespace Microsoft.Extensions.DependencyInjection
if (runtime == Runtime.Server)
{
// register client startup services if running on server
assembly.GetInstances<IClientStartup>()
.ToList()
.ForEach(x => x.ConfigureServices(services));
@ -143,7 +146,7 @@ namespace Microsoft.Extensions.DependencyInjection
var assembliesFolder = new DirectoryInfo(Path.Combine(assemblyPath, culture));
if (assembliesFolder.Exists)
{
foreach (var assemblyFile in assembliesFolder.EnumerateFiles(Constants.StalliteAssemblyExtension))
foreach (var assemblyFile in assembliesFolder.EnumerateFiles(Constants.SatelliteAssemblyExtension))
{
AssemblyName assemblyName;
try

View File

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Oqtane.Modules;
@ -34,7 +34,6 @@ namespace System.Reflection
}
return assembly.GetTypes()
//.Where(t => t.GetInterfaces().Contains(interfaceType));
.Where(x => !x.IsInterface && !x.IsAbstract && interfaceType.IsAssignableFrom(x));
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Globalization;
namespace Oqtane.Shared {
@ -68,7 +68,7 @@ namespace Oqtane.Shared {
};
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;
}