Refactoring

This commit is contained in:
Hisham Bin Ateya 2020-01-03 20:34:33 +03:00
parent cbe33c560f
commit 2fdc01644e
2 changed files with 62 additions and 46 deletions

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace System.Reflection
{
public static class AssemblyExtensions
{
public static IEnumerable<Type> GetInterfaces<TInterfaceType>(this Assembly assembly)
{
if (assembly is null)
{
throw new ArgumentNullException(nameof(assembly));
}
return assembly.GetTypes(typeof(TInterfaceType));
}
public static IEnumerable<Type> GetTypes(this Assembly assembly, Type interfaceType)
{
if (assembly is null)
{
throw new ArgumentNullException(nameof(assembly));
}
if (interfaceType is null)
{
throw new ArgumentNullException(nameof(interfaceType));
}
return assembly.GetTypes()
.Where(t => t.GetInterfaces().Contains(interfaceType));
}
}
}

View File

@ -20,42 +20,14 @@ namespace Microsoft.Extensions.DependencyInjection
public static IServiceCollection AddOqtaneModules(this IServiceCollection services) public static IServiceCollection AddOqtaneModules(this IServiceCollection services)
{ {
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); LoadAssemblies("Module");
var assembliesFolder = new DirectoryInfo(assemblyPath);
// iterate through Oqtane module assemblies in /bin ( filter is narrow to optimize loading process )
foreach (var file in assembliesFolder.EnumerateFiles("*.Module.*.dll"))
{
// check if assembly is already loaded
var assembly = Assemblies.Where(a => a.Location == file.FullName).FirstOrDefault();
if (assembly == null)
{
// load assembly from stream to prevent locking file ( as long as dependencies are in /bin they will load as well )
assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(file.FullName)));
_oqtaneModuleAssemblies.Add(assembly);
}
}
return services; return services;
} }
public static IServiceCollection AddOqtaneThemes(this IServiceCollection services) public static IServiceCollection AddOqtaneThemes(this IServiceCollection services)
{ {
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); LoadAssemblies("Theme");
var assembliesFolder = new DirectoryInfo(assemblyPath);
// iterate through Oqtane theme assemblies in /bin ( filter is narrow to optimize loading process )
foreach (var file in assembliesFolder.EnumerateFiles("*.Theme.*.dll"))
{
// check if assembly is already loaded
var assembly = Assemblies.Where(a => a.Location == file.FullName).FirstOrDefault();
if (assembly == null)
{
// load assembly from stream to prevent locking file ( as long as dependencies are in /bin they will load as well )
assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(file.FullName)));
_oqtaneModuleAssemblies.Add(assembly);
}
}
return services; return services;
} }
@ -67,20 +39,11 @@ namespace Microsoft.Extensions.DependencyInjection
Where(item => item.FullName.StartsWith("Oqtane.") || item.FullName.Contains(".Module.")).ToArray(); Where(item => item.FullName.StartsWith("Oqtane.") || item.FullName.Contains(".Module.")).ToArray();
foreach (var assembly in assemblies) foreach (var assembly in assemblies)
{ {
var implementationTypes = assembly.GetTypes() var implementationTypes = assembly.GetInterfaces<IService>();
.Where(t => t.GetInterfaces().Contains(typeof(IService)))
.ToArray();
foreach (var implementationType in implementationTypes) foreach (var implementationType in implementationTypes)
{ {
var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, "I" + implementationType.Name)); var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, $"I{implementationType.Name}"));
if (serviceType != null) services.AddScoped(serviceType ?? implementationType, implementationType);
{
services.AddScoped(serviceType, implementationType); // traditional service interface
}
else
{
services.AddScoped(implementationType, implementationType); // no interface defined for service
}
} }
} }
@ -90,21 +53,39 @@ namespace Microsoft.Extensions.DependencyInjection
public static IServiceCollection AddOqtaneHostedServices(this IServiceCollection services) public static IServiceCollection AddOqtaneHostedServices(this IServiceCollection services)
{ {
// dynamically register hosted services // dynamically register hosted services
var hostedServiceType = typeof(IHostedService);
foreach (var assembly in Assemblies) foreach (var assembly in Assemblies)
{ {
var serviceTypes = assembly.GetTypes() var serviceTypes = assembly.GetTypes(hostedServiceType);
.Where(t => t.GetInterfaces().Contains(typeof(IHostedService)))
.ToArray();
foreach (var serviceType in serviceTypes) foreach (var serviceType in serviceTypes)
{ {
if (serviceType.Name != nameof(HostedServiceBase)) if (serviceType.Name != nameof(HostedServiceBase))
{ {
services.AddSingleton(typeof(IHostedService), serviceType); services.AddSingleton(hostedServiceType, serviceType);
} }
} }
} }
return services; return services;
} }
private static void LoadAssemblies(string pattern)
{
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var assembliesFolder = new DirectoryInfo(assemblyPath);
// iterate through Oqtane theme assemblies in /bin ( filter is narrow to optimize loading process )
foreach (var file in assembliesFolder.EnumerateFiles($"*.{pattern}.*.dll"))
{
// check if assembly is already loaded
var assembly = Assemblies.Where(a => a.Location == file.FullName).FirstOrDefault();
if (assembly == null)
{
// load assembly from stream to prevent locking file ( as long as dependencies are in /bin they will load as well )
assembly = AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(File.ReadAllBytes(file.FullName)));
_oqtaneModuleAssemblies.Add(assembly);
}
}
}
} }
} }