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; + } } } +