implementation of [OqtaneIgnore] class attribute in controls

This commit is contained in:
Pavel Vesely
2020-05-07 18:51:55 +02:00
parent 6586883979
commit 47f17a589f
31 changed files with 227 additions and 178 deletions

View File

@ -5,67 +5,35 @@ using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Microsoft.Extensions.Hosting;
using Oqtane.Extensions;
using Oqtane.Infrastructure;
using Oqtane.Modules;
using Oqtane.Shared;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
{
public static class OqtaneServiceCollectionExtensions
{
private static readonly IList<Assembly> OqtaneModuleAssemblies = new List<Assembly>();
private static Assembly[] Assemblies => AppDomain.CurrentDomain.GetAssemblies();
internal static IEnumerable<Assembly> GetOqtaneModuleAssemblies() => OqtaneModuleAssemblies;
public static IServiceCollection AddOqtaneModules(this IServiceCollection services)
public static IServiceCollection AddOqtaneParts(this IServiceCollection services)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}
LoadAssemblies("Module");
LoadAssemblies();
services.AddOqtaneServices();
return services;
}
public static IServiceCollection AddOqtaneThemes(this IServiceCollection services)
private static IServiceCollection AddOqtaneServices(this IServiceCollection services)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}
LoadAssemblies("Theme");
return services;
}
public static IServiceCollection AddOqtaneSiteTemplates(this IServiceCollection services)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}
LoadAssemblies("SiteTemplate");
return services;
}
public static IServiceCollection AddOqtaneServices(this IServiceCollection services)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}
// dynamically register module services, contexts, and repository classes
var assemblies = Assemblies.Where(item => item.FullName != null && (item.FullName.StartsWith("Oqtane.") || item.FullName.Contains(".Module."))).ToArray();
var hostedServiceType = typeof(IHostedService);
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
foreach (var assembly in assemblies)
{
// dynamically register module services, contexts, and repository classes
var implementationTypes = assembly.GetInterfaces<IService>();
foreach (var implementationType in implementationTypes)
{
@ -75,22 +43,8 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddScoped(serviceType ?? implementationType, implementationType);
}
}
}
return services;
}
public static IServiceCollection AddOqtaneHostedServices(this IServiceCollection services)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}
// dynamically register hosted services
var hostedServiceType = typeof(IHostedService);
foreach (var assembly in Assemblies)
{
// dynamically register hosted services
var serviceTypes = assembly.GetTypes(hostedServiceType);
foreach (var serviceType in serviceTypes)
{
@ -104,34 +58,50 @@ namespace Microsoft.Extensions.DependencyInjection
return services;
}
private static void LoadAssemblies(string pattern)
private static void LoadAssemblies()
{
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
if (assemblyPath == null) return;
var assembliesFolder = new DirectoryInfo(assemblyPath);
// iterate through Oqtane assemblies in /bin ( filter is narrow to optimize loading process )
foreach (var dll in assembliesFolder.EnumerateFiles($"*.{pattern}.*.dll"))
foreach (var dll in assembliesFolder.EnumerateFiles($"*.dll", SearchOption.TopDirectoryOnly).Where(f => f.IsOqtaneAssembly()))
{
// check if assembly is already loaded
var assembly = Assemblies.FirstOrDefault(a =>!a.IsDynamic && a.Location == dll.FullName);
if (assembly == null)
AssemblyName assemblyName;
try
{
// load assembly ( and symbols ) from stream to prevent locking files ( as long as dependencies are in /bin they will load as well )
string pdb = dll.FullName.Replace(".dll", ".pdb");
if (File.Exists(pdb))
assemblyName = AssemblyName.GetAssemblyName(dll.FullName);
}
catch
{
Console.WriteLine($"Not Assembly : {dll.Name}");
continue;
}
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
if (!assemblies.Any(a => AssemblyName.ReferenceMatchesDefinition(assemblyName, a.GetName())))
{
try
{
assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(dll.FullName)), new MemoryStream(File.ReadAllBytes(pdb)));
var pdb = Path.ChangeExtension(dll.FullName, ".pdb");
Assembly assembly = null;
// load assembly ( and symbols ) from stream to prevent locking files ( as long as dependencies are in /bin they will load as well )
if (File.Exists(pdb))
{
assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(dll.FullName)), new MemoryStream(File.ReadAllBytes(pdb)));
}
else
{
assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(dll.FullName)));
}
Console.WriteLine($"Loaded : {assemblyName}");
}
else
catch (Exception e)
{
assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(dll.FullName)));
}
if (pattern == "Module")
{
// build a list of module assemblies
OqtaneModuleAssemblies.Add(assembly);
Console.WriteLine($"Failed : {assemblyName}\n{e}");
}
}
}