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"]);
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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));
        }
Пример #4
0
 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));
 }
Пример #5
0
 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));
 }
Пример #6
0
 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));
 }
Пример #7
0
        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));
        }
Пример #8
0
        /// <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());
        }
Пример #9
0
        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));
        }
Пример #10
0
 /// <summary>
 /// Initializes this deferred initializable object
 /// </summary>
 public void Initialize()
 {
     if (!Initialized)
     {
         try
         {
             Instance = factory.LoadPlugin <IPlugin>(UniqueName, constructor);
         }
         finally
         {
             Initialized = true;
         }
     }
 }
Пример #11
0
        /// <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));
        }
Пример #14
0
        /// <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");
                }
            }
        }
Пример #15
0
        /// <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);
        }
Пример #16
0
        /// <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);
        }
Пример #17
0
 /// <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));
 }