private IEnumerable <string> LoadPlugins() { using (database.AcquireConnection(false, out var db)) { DynamicResult[] plugins = db.GetNativeResults($"Select * from {tableName} where isnull(disabled,0)=0 order by LoadOrder", null); foreach (DynamicResult plugin in plugins) { if (factory[plugin["UniqueName"]] == null) { bool ok = false; try { factory.LoadPlugin <IPlugin>(plugin["UniqueName"], plugin["Constructor"]); ok = true; } catch (Exception ex) { LogEnvironment.LogDebugEvent(ex.OutlineException(), LogSeverity.Error); db.ExecuteCommand( $"Update {tableName} set disabled = 1, disabledreason = @reason where pluginid = @pluginId", db.GetParameter("pluginid", plugin["pluginId"]), db.GetParameter("reason", ex.Message)); } if (ok) { yield return(plugin["UniqueName"]); } } } } }
/// <summary> /// Gets an available Database Connection from the pool of available connections /// </summary> /// <param name="useTransaction">indicates whether to begin a transaction for the returned database connection</param> /// <param name="database">the database that is available for usage</param> /// <returns>a connection that is unused at the moment</returns> public IResourceLock AcquireConnection(bool useTransaction, out IDbWrapper database) { while (!disposed) { try { database = factory.LoadPlugin <IDbWrapper>("dummy", databaseConstructor, false); ITransaction trans = null; if (useTransaction) { trans = database.AcquireTransaction(); } OnConnectionAcquiring(database); return(new ResourceDisposer(database, trans)); } catch (Exception ex) { LogEnvironment.LogEvent(ex.Message, LogSeverity.Error, "DataAccess"); } } database = null; return(null); }
/// <summary> /// Acquires a connection using the desired Context-Plugin /// </summary> /// <typeparam name="TContext">the context - type that is used to access the database</typeparam> /// <param name="context">holds the context that was loaded using the pluginFactory</param> /// <returns>a resource-lock that will dispose the context after using</returns> public IResourceLock AcquireContext <TContext>(out TContext context) where TContext : DbContext { IPlugin tmp = factory.LoadPlugin <IPlugin>("dummy", contextConstructor, false); context = (TContext)tmp; return(new ResourceDisposer(context)); }
public static void LoadPlugin_DllDoesNotImplementIPlugin_EntryPointNotFoundException() { Assert.Throws <EntryPointNotFoundException>(() => { PluginFactory.LoadPlugin("Logger.dll", "TestReader"); }, "{0}.{1}() should throw a {2} when passed a DLL that doesn't implement the IPlugin interface!", nameof(PluginFactory), nameof(PluginFactory.LoadPlugin), nameof(EntryPointNotFoundException)); }
public static void LoadPlugin_MissingDll_DllNotFoundException() { Assert.Throws <DllNotFoundException>(() => { PluginFactory.LoadPlugin("foo.dll", "bar.xml"); }, "{0}.{1}() should throw a {2} when passed a non-existent DLL!", nameof(PluginFactory), nameof(PluginFactory.LoadPlugin), nameof(DllNotFoundException)); }
public static void LoadPlugin_NullOrWhiteSpaceArgs_ArgumentNullException(string dllFile, string xmlConfig) { Assert.Throws <ArgumentNullException>(() => { PluginFactory.LoadPlugin(dllFile, xmlConfig); }, "{0}.{1}() should throw a {2} when null arguments are passed in!", nameof(PluginFactory), nameof(PluginFactory.LoadPlugin), nameof(ArgumentNullException)); }
private IDatabasePlugin ChooseDatabase(params string[] pluginNames) { Console.WriteLine("Loading database plugins..."); var factory = new PluginFactory(); var availablePlugins = pluginNames .SelectMany(name => factory.LoadPlugin <IDatabasePlugin>(Assembly.GetExecutingAssembly(), name)) .ToArray(); return(Choose("Select database plugin:", x => x.Name, availablePlugins)); }
/// <summary> /// Initializes the workers driven by this service /// </summary> private void SetupWorkers() { foreach (PluginConfigurationItem pi in ServiceConfigHelper.PlugIns) { if (!pi.Disabled) { pluginLoader.LoadPlugin <IPlugin>(pi.Name, pi.ConstructionString); } } pluginLoader.LoadRuntimeStatus(); pluginLoader.InitializeDeferrables(ServiceConfigHelper.PlugIns.Where(n => !n.Disabled).Select(n => n.Name).ToArray()); }
public static void LoadPlugin_ValidArgs_ReturnsIPlugin() { IPlugin plugin = null; Assert.DoesNotThrow(() => { plugin = PluginFactory.LoadPlugin("NullPlugin.dll", "TestReader"); }, "{0}.{1}() should not throw an exception when passed a valid DLL file!", nameof(PluginFactory), nameof(PluginFactory.LoadPlugin)); Assert.NotNull(plugin, "{0}.{1}() returned null when passed a valid DLL file!", nameof(PluginFactory), nameof(PluginFactory.LoadPlugin)); }
/// <summary> /// Initializes this deferred initializable object /// </summary> public void Initialize() { if (!Initialized) { try { Instance = factory.LoadPlugin <IPlugin>(UniqueName, constructor); } finally { Initialized = true; } } }
/// <summary> /// Invoked to configure a <typeparamref name="TOptions" /> instance. /// </summary> /// <param name="options">The options instance to configure.</param> public void Configure(PluginsInitOptions options) { options.SetParent(globalInit); options.Init(() => { try { plugLogger.LogDebug("Creating service scope..."); using (var scope = serviceProvider.CreateScope()) { var pluginProvider = scope.ServiceProvider.GetService <IWebPluginsSelector>(); PluginFactory noBufFactory; using (noBufFactory = new PluginFactory(false)) { plugLogger.LogDebug("Enumerating Startup-Plugins"); foreach (var plug in pluginProvider.GetStartupPlugins()) { try { plugLogger.LogDebug($"Initializing {plug.UniqueName}"); using (var plugInst = noBufFactory.LoadPlugin <IPlugin>(plug.UniqueName, plug.StartupRegistrationConstructor)) { if (plugInst is IDependencyInit init) { init.Initialize(scope.ServiceProvider); } } } catch (Exception ex) { plugLogger.LogError(ex, "Error on performing auto-load of plugins"); } } plugLogger.LogDebug("Done"); } } } catch (Exception ex) { plugLogger.LogError(ex, "Error on preparing Plugins-Autoload"); } }); }
/// <summary> /// Initializes a singleton plugin /// </summary> /// <param name="uniqueName">the unique name of the plugin that is being initialized</param> /// <param name="constructorString">the constructor of the demanded plugin</param> /// <param name="buffer">indicates whether to buffer the requested item</param> /// <param name="unknownParameterCallback">a callback that is used to resolve unkown constructor arguments</param> /// <returns>a value indicating whether to buffer the item on the local factory or not</returns> internal static IPlugin InitializeSingletonPlugin(string uniqueName, string constructorString, bool buffer, UnknownConstructorParameterEventHandler unknownParameterCallback) { CheckInitialized(); lock (initializationLock) { bool registered = RegisterLocalCallback(unknownParameterCallback); try { return(singletonFactory.LoadPlugin <IPlugin>(uniqueName, constructorString, buffer)); } finally { if (registered) { UnregisterLocalCallback(); } } } }
public static IServiceCollection AddConfigPlugins(this IServiceCollection container, Config config) { Assembly sourcePlugin = PluginFactory.LoadPlugin(config.Source); Type sourcePluginType = PluginFactory.GetPluginType <ISource>(sourcePlugin); container .AddPluginServices(sourcePlugin) .AddSingleton(typeof(ISource), sourcePluginType); IEnumerable <Assembly> generatorPlugins = config.Generators.Select(PluginFactory.LoadPlugin); foreach (Assembly generatorPlugin in generatorPlugins) { container .AddPluginServices(generatorPlugin) .AddSingleton(typeof(IGenerator), PluginFactory.GetPluginType <IGenerator>(generatorPlugin)); } return(container.AddSingleton(config)); }
/// <summary> /// Sets up the factory and loads autoload-configured plugins /// </summary> private void SetupFactory(PluginFactory factory) { foreach (WebPlugin pi in pluginProvider.GetAutoLoadPlugins()) { try { if (serviceProvider.VerifyUserPermissions(new [] { pi.UniqueName }, true)) { factory.LoadPlugin <IPlugin>(pi.UniqueName, pi.Constructor); } } catch (Exception ex) { //pi.AutoLoad = false; //pluginProvider.ConfigurePlugin(pi); logger.LogError($@"Plugin failed to load. Error: {ex.OutlineException()} Section: Plugins", ex, "Plugins"); } } }
/// <summary> /// Gets an available Database Connection from the pool of available connections /// </summary> /// <param name="useTransaction">indicates whether to begin a transaction for the returned database connection</param> /// <param name="database">the database that is available for usage</param> /// <returns>a connection that is unused at the moment</returns> public IResourceLock AcquireConnection(bool useTransaction, out IDbWrapper database) { string threadId = Thread.CurrentThread.LocalOwner(); DatabaseContainer db; IResourceLock inner = null; while (!disposing) { try { lock (connections) { var tmp = (from t in connections where !t.InUse && !t.Disposed && t.ThreadId == threadId select t).FirstOrDefault (); if (tmp != null) { tmp.InUse = true; tmp.LastUsage = DateTime.Now; } db = tmp; } if (db == null) { db = new DatabaseContainer { Database = factory.LoadPlugin <IDbWrapper>(DataAccessResources.ParallelDummyInstanceName, databaseConstructor, false), LastUsage = DateTime.Now, InUse = true, ThreadId = threadId }; lock (connections) { connections.Add(db); } } if (useTransaction) { inner = db.Database.AcquireTransaction(); } database = db.Database; lock (activeConnectionLock) { activeConnectionCount++; } OnConnectionAcquiring(database); return(new DataBufferResourceLock(this, db, inner)); } catch (Exception ex) { LogEnvironment.LogEvent(ex.Message, LogSeverity.Error, "DataAccess"); } } database = null; return(null); }
/// <summary> /// Initializes a new i PluginFactory instance /// </summary> /// <returns>a Factory that can be used to load further plugins</returns> private PluginFactory CreateFactory() { var retVal = new PluginFactory(); LogEnvironment.OpenRegistrationTicket(retVal); retVal.AllowFactoryParameter = true; retVal.RegisterObject(Global.ServiceProviderName, serviceProvider); UnknownConstructorParameterEventHandler handler = (sender, args) => { PluginFactory pi = (PluginFactory)sender; IWebPluginsSelector availablePlugins = pluginProvider; var globalProvider = serviceProvider.GetService <IGlobalSettingsProvider>(); var tenantProvider = serviceProvider.GetService <IScopedSettingsProvider>(); var preInitializationSequence = tenantProvider?.GetJsonSetting($"PreInitSequenceFor{args.RequestedName}") ?? globalProvider?.GetJsonSetting($"PreInitSequenceFor{args.RequestedName}"); var postInitializationSequence = tenantProvider?.GetJsonSetting($"PostInitSequenceFor{args.RequestedName}") ?? globalProvider?.GetJsonSetting($"PostInitSequenceFor{args.RequestedName}"); var preInitSequence = DeserializeInitArray(preInitializationSequence); var postInitSequence = DeserializeInitArray(postInitializationSequence); WebPlugin plugin = availablePlugins.GetPlugin(args.RequestedName); if (plugin != null) { if (serviceProvider.VerifyUserPermissions(new [] { args.RequestedName }, true)) { if (preInitSequence.Length != 0) { foreach (var s in preInitSequence) { var tmp = pi[s, true]; } } if (!string.IsNullOrEmpty(plugin.Constructor)) { args.Value = pi.LoadPlugin <IPlugin>(plugin.UniqueName, plugin.Constructor); args.Handled = true; } if (postInitSequence.Length != 0) { foreach (var s in postInitSequence) { var tmp = pi[s, true]; } } } } else { var tmp = factoryOptions?.GetDependency(args.RequestedName, serviceProvider); args.Handled = tmp != null; args.Value = tmp; } }; void Initializer(object sender, PluginInitializedEventArgs args) { PluginLoadInterceptHelper.RunInterceptors(retVal, args.Plugin); } void Finalizer(object sender, EventArgs e) { LogEnvironment.DisposeRegistrationTicket(sender); var pi = (PluginFactory)sender; var dp = (IServiceProvider)pi.GetRegisteredObject(Global.ServiceProviderName); if (dp != null) { factory = null; } pi.Disposed -= Finalizer; pi.UnknownConstructorParameter -= handler; pi.PluginInitialized -= Initializer; pi.ImplementGenericType -= Implementer; } void Implementer(object sender, ImplementGenericTypeEventArgs args) { PluginFactory pi = (PluginFactory)sender; IWebPluginsSelector availablePlugins = pluginProvider; var impl = availablePlugins.GetGenericParameters(args.PluginUniqueName); if (impl != null) { var dic = new Dictionary <string, object>(); var assignments = (from t in args.GenericTypes join a in impl on t.GenericTypeName equals a.GenericTypeName select new { Arg = t, Type = a.TypeExpression }); foreach (var item in assignments) { item.Arg.TypeResult = (Type)ExpressionParser.Parse(item.Type.ApplyFormat(args), dic); } args.Handled = true; } } retVal.UnknownConstructorParameter += handler; retVal.PluginInitialized += Initializer; retVal.Disposed += Finalizer; retVal.ImplementGenericType += Implementer; return(retVal); }
/// <summary> /// Initializes a Wrapper object defined by the provided constructor string /// </summary> /// <param name="constructorString">a plugin string for loading a db component</param> /// <returns>a created wrapper</returns> public IDbWrapper GetWrapper(string constructorString) { return(innerFactory.LoadPlugin <IDbWrapper>(".", constructorString)); }