implementation of [OqtaneIgnore] class attribute in controls
This commit is contained in:
@ -1,5 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Oqtane.Shared;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace System.Reflection
|
||||
@ -31,5 +33,20 @@ namespace System.Reflection
|
||||
return assembly.GetTypes()
|
||||
.Where(t => t.GetInterfaces().Contains(interfaceType));
|
||||
}
|
||||
|
||||
public static bool IsOqtaneAssembly(this Assembly assembly)
|
||||
{
|
||||
return assembly.FullName != null && (assembly.FullName.Contains("oqtane.", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public static bool IsOqtaneAssembly(this FileInfo fileInfo)
|
||||
{
|
||||
return (fileInfo.Name.Contains("oqtane.", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public static IEnumerable<Assembly> GetOqtaneAssemblies(this AppDomain appDomain)
|
||||
{
|
||||
return appDomain.GetAssemblies().Where(a => a.IsOqtaneAssembly());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
|
||||
@ -16,10 +17,11 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||
}
|
||||
|
||||
// load MVC application parts from module assemblies
|
||||
foreach (var assembly in OqtaneServiceCollectionExtensions.GetOqtaneModuleAssemblies())
|
||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies();
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
// check if assembly contains MVC Controllers
|
||||
if (assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(Controller))).ToArray().Length > 0)
|
||||
if (assembly.GetTypes().Any(t => t.IsSubclassOf(typeof(Controller))))
|
||||
{
|
||||
var partFactory = ApplicationPartFactory.GetApplicationPartFactory(assembly);
|
||||
foreach (var part in partFactory.GetApplicationParts(assembly))
|
||||
|
@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
17
Oqtane.Server/Extensions/StringExtensions.cs
Normal file
17
Oqtane.Server/Extensions/StringExtensions.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Oqtane.Extensions
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static bool StartWithAnyOf(this string s, IEnumerable<string> list)
|
||||
{
|
||||
if (s == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return list.Any(f => s.StartsWith(f));
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user