From 7725cc3b0524c20a70cbedfe0f1b6add85d5de57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Antoine=20Th=C3=A9ate?=
<97221392+antoineatstariongroup@users.noreply.github.com>
Date: Fri, 24 Jan 2025 13:01:10 +0100
Subject: [PATCH] Fix bug on DLL resolve for plugins (#380)
* Fix bug on DLL resolve for plugins
* Increase waiting time
---
.github/workflows/CodeQuality.yml | 2 +-
.../AuthenticationPluginInjector.cs | 38 +++++++++++++++++--
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/CodeQuality.yml b/.github/workflows/CodeQuality.yml
index e548219f..de987574 100644
--- a/.github/workflows/CodeQuality.yml
+++ b/.github/workflows/CodeQuality.yml
@@ -79,7 +79,7 @@ jobs:
run: dotnet-coverage collect --output CoverageResults/integration.test.report.coverage.xml --output-format cobertura --session-id integrationtestsession "dotnet run --project CometServer/CometServer.csproj -c Debug" &
- name: Wait for API to start
- run: sleep 45 # Adjust as necessary to ensure the API is up
+ run: sleep 60 # Adjust as necessary to ensure the API is up
- name: Checkout Integration Test Suite
uses: actions/checkout@v4
diff --git a/CometServer/Authentication/AuthenticationPluginInjector.cs b/CometServer/Authentication/AuthenticationPluginInjector.cs
index b0832ee4..146d9c84 100644
--- a/CometServer/Authentication/AuthenticationPluginInjector.cs
+++ b/CometServer/Authentication/AuthenticationPluginInjector.cs
@@ -41,8 +41,13 @@ namespace CometServer.Authentication
///
/// The injector loads up authenticator plugins.
///
- public class AuthenticationPluginInjector : IAuthenticationPluginInjector
+ public class AuthenticationPluginInjector : IAuthenticationPluginInjector, IDisposable
{
+ ///
+ /// A collection of that has been discovered
+ ///
+ private List discoveredAssemblies = new List();
+
///
/// The name of the folder where all authentication modules reside.
///
@@ -59,6 +64,7 @@ public class AuthenticationPluginInjector : IAuthenticationPluginInjector
public AuthenticationPluginInjector(ILogger logger)
{
this.logger = logger;
+ AppDomain.CurrentDomain.AssemblyResolve += this.OnAssemblyResolve;
this.Plugins = this.LoadPlugins();
@@ -103,6 +109,7 @@ private static string[] GetFolders()
/// The of modules
private ReadOnlyCollection LoadPlugins()
{
+ this.discoveredAssemblies.Clear();
var sw = Stopwatch.StartNew();
var result = new List();
@@ -116,8 +123,11 @@ private ReadOnlyCollection LoadPlugins()
// load all assemblies types encountered in the plugin folders that implement the IAuthenticatorPlugin interface
foreach (var pluginFolder in pluginFolders)
{
- foreach (var assembly in new DirectoryInfo(pluginFolder).GetFiles().Where(file => file.Extension == ".dll")
- .Select(file => Assembly.LoadFile(file.FullName)))
+ var assemblies = new DirectoryInfo(pluginFolder).GetFiles().Where(file => file.Extension == ".dll")
+ .Select(file => Assembly.LoadFile(file.FullName))
+ .ToList();
+
+ foreach (var assembly in assemblies)
{
builder.RegisterAssemblyTypes(assembly)
.Where(x => typeof(IAuthenticatorPlugin).IsAssignableFrom(x))
@@ -125,6 +135,8 @@ private ReadOnlyCollection LoadPlugins()
.PropertiesAutowired()
.SingleInstance();
}
+
+ this.discoveredAssemblies.AddRange(assemblies);
}
var container = builder.Build();
@@ -138,5 +150,25 @@ private ReadOnlyCollection LoadPlugins()
return result.AsReadOnly();
}
+
+ ///
+ /// Helps resolving assemblies that may be required for loaded plugins
+ ///
+ /// The sender object
+ /// The
+ /// The resolved assemblies, if found
+ private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
+ {
+ return this.discoveredAssemblies.FirstOrDefault(x => x.FullName == args.Name);
+ }
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ AppDomain.CurrentDomain.AssemblyResolve -= this.OnAssemblyResolve;
+ }
}
}
+