diff options
author | vman <public@vaughnnugent.com> | 2022-11-18 16:01:38 -0500 |
---|---|---|
committer | vman <public@vaughnnugent.com> | 2022-11-18 16:01:38 -0500 |
commit | ae7d863808c6c00999d20408beeda3731509c40c (patch) | |
tree | 939de3a994e614af88c4fba522dadb251d6b85db /VNLib.Plugins.Extensions.Loading/UserLoading.cs | |
parent | 3fb601d14354c867e1ead94b027c99c4a2fc15b5 (diff) |
Namespace changes and dynamic user lib loading
Diffstat (limited to 'VNLib.Plugins.Extensions.Loading/UserLoading.cs')
-rw-r--r-- | VNLib.Plugins.Extensions.Loading/UserLoading.cs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/VNLib.Plugins.Extensions.Loading/UserLoading.cs b/VNLib.Plugins.Extensions.Loading/UserLoading.cs new file mode 100644 index 0000000..ae55094 --- /dev/null +++ b/VNLib.Plugins.Extensions.Loading/UserLoading.cs @@ -0,0 +1,84 @@ +using System; +using System.Linq; +using System.Threading; +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +using VNLib.Utils.Logging; +using VNLib.Utils.Extensions; +using VNLib.Plugins.Essentials.Users; + +namespace VNLib.Plugins.Extensions.Loading.Users +{ + /// <summary> + /// Contains extension methods for plugins to load the "users" system + /// </summary> + public static class UserLoading + { + public const string USER_CUSTOM_ASSEMBLY = "user_custom_asm"; + public const string DEFAULT_USER_ASM = "VNLib.Plugins.Essentials.Users.dll"; + public const string ONLOAD_METHOD_NAME = "OnPluginLoading"; + + private static readonly ConditionalWeakTable<PluginBase, Lazy<IUserManager>> UsersTable = new(); + + /// <summary> + /// Gets or loads the plugin's ambient <see cref="IUserManager"/>, with the specified user-table name, + /// or the default table name + /// </summary> + /// <param name="plugin"></param> + /// <returns>The ambient <see cref="IUserManager"/> for the current plugin</returns> + /// <exception cref="KeyNotFoundException"></exception> + /// <exception cref="ObjectDisposedException"></exception> + public static IUserManager GetUserManager(this PluginBase plugin) + { + plugin.ThrowIfUnloaded(); + //Get stored or load + return UsersTable.GetValue(plugin, LoadUsers).Value; + } + + private static Lazy<IUserManager> LoadUsers(PluginBase pbase) + { + //lazy callack + IUserManager LoadManager() + { + //Try to load a custom user assembly for exporting IUserManager + string? customAsm = pbase.PluginConfig.GetPropString(USER_CUSTOM_ASSEMBLY); + //See if host config defined the path + customAsm ??= pbase.HostConfig.GetPropString(USER_CUSTOM_ASSEMBLY); + //Finally default + customAsm ??= DEFAULT_USER_ASM; + + //Try to load a custom assembly + AssemblyLoader<IUserManager> loader = pbase.LoadAssembly<IUserManager>(customAsm); + try + { + //Get the runtime type + Type runtimeType = loader.Resource.GetType(); + + //Get the onplugin load method + Action<object>? onLoadMethod = runtimeType.GetMethods() + .Where(static p => p.IsPublic && !p.IsAbstract && ONLOAD_METHOD_NAME.Equals(p.Name)) + .Select(p => p.CreateDelegate<Action<object>>(loader.Resource)) + .FirstOrDefault(); + + //Call the onplugin load method + onLoadMethod?.Invoke(pbase); + + if (pbase.IsDebug()) + { + pbase.Log.Verbose("Loading user manager from assembly {name}", runtimeType.AssemblyQualifiedName); + } + + //Return the loaded instance (may raise exception) + return loader.Resource; + } + catch + { + loader.Dispose(); + throw; + } + } + return new Lazy<IUserManager>(LoadManager, LazyThreadSafetyMode.PublicationOnly); + } + } +}
\ No newline at end of file |