Beispiel #1
0
        /// <summary>
        /// Each channel is run in a different thread to prevent interference with other channels.
        /// </summary>
        void _ThreadLoop()
        {
            Action action;

            while (!AppDomain.CurrentDomain.IsFinalizingForUnload() && !_Closing)
            {
                while (_Actions.Count > 0)
                {
                    lock (_Actions)
                    {
                        action = _Actions.Dequeue();
                    }
                    try
                    {
                        action();
                    }
                    catch (Exception ex)
                    {
                        _LastError = ICEController.WriteICEEventError("A queued action '" + action.Method.Name + "' for channel '" + Name + " (" + _GUID + ")' has caused an exception error.", ex);
                    }
                }

                Thread.Sleep(0);
            }
        }
Beispiel #2
0
        public static bool AddAssembly(string filename, bool throwErrors = false)
        {
            if (!File.Exists(filename))
            {
                var _ex = ICEController.WriteICEEventError("The plugin library (Assembly) file '" + filename + "' does not exist.");
                if (throwErrors)
                {
                    throw _ex;
                }
                return(false);
            }

            Assembly assembly;

            try
            {
                assembly = Assembly.ReflectionOnlyLoadFrom(filename);
            }
            catch (Exception ex)
            {
                var _ex = ICEController.WriteICEEventError("The plugin library (Assembly) file '" + filename + "' is invalid or cannot be loaded for some reason.", ex);
                if (throwErrors)
                {
                    throw _ex;
                }
                return(false);
            }

            return(AddAssembly(assembly, throwErrors));
        }
Beispiel #3
0
        /// <summary>
        /// Returns a list of valid plugin types from the specified assembly.
        /// </summary>
        /// <param name="assembly">The assembly to search.</param>
        /// <param name="suppressErrors">If true, then any exception errors are ignored, and 'null' is returned instead.  Any errors are still recorded in the
        /// event log however.</param>
        public static Type[] GetICEPluginTypes(this Assembly assembly, bool suppressErrors = true)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }

            try
            {
                List <Type> appList = new List <Type>();

                var types = assembly.GetTypes();

                foreach (var type in types)
                {
                    if (type.IsClass && !type.IsAbstract && typeof(IPlugin).IsAssignableFrom(type))
                    {
                        appList.Add(type);
                    }
                }

                return(appList.ToArray());
            }
            catch (Exception ex)
            {
                var _ex = ICEController.WriteICEEventError("Failed to retrieve plugin types from assembly '" + assembly.FullName + "'.", ex);
                if (!suppressErrors)
                {
                    throw _ex;
                }

                return(new Type[0]); // (error not desired, so return an empty array)
            }
        }
Beispiel #4
0
        /// <summary>
        /// Attempts to load the assembly for this plugin library. Returns true on success, and false otherwise.
        /// </summary>
        /// <param name="throwErrors">If true, then an exception is thrown instead of returning false.</param>
        public bool Load(bool throwErrors = false)
        {
            if (_Assembly == null || _Assembly.ReflectionOnly)
            {
                if (string.IsNullOrEmpty(_Filename))
                {
                    var _ex = ICEController.WriteICEEventError("Cannot load this library: No valid filename was given.");
                    if (throwErrors)
                    {
                        throw _ex;
                    }
                    return(false);
                }

                string libFileToLoad = AppDomain.CurrentDomain.BaseDirectory + _Filename;

                ICEController.WriteICEEventInfo("Loading library '" + libFileToLoad + "'...");

                try
                {
                    _Assembly = Assembly.LoadFile(libFileToLoad);
                }
                catch (Exception ex)
                {
                    var _ex = ICEController.WriteICEEventError("An error occurred trying to load plugin '" + libFileToLoad + "'.", ex);
                    if (throwErrors)
                    {
                        throw _ex;
                    }
                    return(false);
                }
            }

            return(IsLoaded);
        }
Beispiel #5
0
        // -------------------------------------------------------------------------------------------------------

        /// <summary>
        /// Creates and returns a plugin instance to run on a given channel.
        /// </summary>
        /// <param name="channel">The channel instance to create the plugin in (required).</param>
        /// <param name="name">The case-sensitive type name, or full type name (i.e. [Namespace].[Type]), of the plugin to create.  Full type names are
        /// searched first before type-only names.</param>
        /// <param name="guid">A globally unique ID for this plugin instance (system wide, across all channels). If null or empty, a new GUID will be created automatically.</param>
        public Plugin <IPlugin> CreateInstance(Channel channel, string instanceName, string guid = null)
        {
            if (channel == null)
            {
                throw new ArgumentNullException("A channel reference is required for plugin instances.");
            }

            if (string.IsNullOrEmpty(guid))
            {
                guid = Guid.NewGuid().ToString("N");
            }

            if (channel.GetPluginInstance(instanceName) != null)
            {
                throw new InvalidOperationException("There is already an existing plugin instance with the name '" + instanceName + "'.");
            }

            Plugin <IPlugin> pluginController = null;

            try
            {
                ICEController.WriteICEEventInfo("Creating instance for plugin '" + PluginType.FullName + "' on channel '" + channel.Name + "'...");

                var pluginInstance = PluginType.Assembly.CreateInstance(PluginType.FullName) as IPlugin;

                pluginController = pluginInstance as Plugin <IPlugin>;

                if (pluginInstance != null && pluginController == null)
                {
                    // ... this plugin instance does not derive from the plugin<T> controller class, so we need to wrap it in one ...
                    pluginController         = new Plugin <IPlugin>();
                    pluginController._Plugin = pluginInstance;
                }

                if (pluginController != null)
                {
                    pluginController._Configure(channel, Library, instanceName, pluginController.ActualPlugin, guid);
                }
            }
            catch (Exception ex)
            {
                throw ICEController.WriteICEEventError("Error creating plugin type '" + PluginType.FullName + "'.", ex);
            }

            return(pluginController);
        }
Beispiel #6
0
        /// <summary>
        /// Adds an assembly to the assembly list, returning 'false' if any errors occur, or if the assembly was already added.
        /// <para>Warning: This method recursively traverses the assembly types, and all dependent types, in real-time, and will add any other associated
        /// applications, components, and controls also.</para>
        /// </summary>
        /// <param name="assembly">The assembly to add, which represents a library of plugin types.</param>
        /// <param name="throwErrors">If true, any errors will throw an exception instead of returning false.</param>
        public static bool AddAssembly(Assembly assembly, bool throwErrors = false)
        {
            if (GetLibrary(assembly) == null)
            {
                try
                {
                    if (assembly.GetICEPluginTypes(true).Length == 0)
                    {
                        return(false); // (there are no valid plugins types in this assembly)
                    }
                    var library = AddLibrary(new Library(assembly));

                    var associatedAssemblies = assembly.GetAssociatedAssemblies(); // (get a list of assemblies other than the given 'assembly')

                    if (associatedAssemblies != null)
                    {
                        foreach (var asm in associatedAssemblies)
                        {
                            AddAssembly(asm, throwErrors);
                        }
                    }
                }
                catch (Exception ex)
                {
                    var _ex = ICEController.WriteICEEventError("Failed to read types in plugin assembly '" + assembly.FullName + "' (a DLL may be missing).", ex);
                    if (throwErrors)
                    {
                        throw _ex;
                    }
                    return(false);
                }

                return(true);
            }

            return(false);
        }
Beispiel #7
0
 /// <summary>
 /// Joins all given parameters into one error message.
 /// </summary>
 /// <param name="strings">The strings to use as a single error message.</param>
 public void SetErrorMessage(params string[] strings)
 {
     _Error = ICEController.WriteICEEventError(strings.Length > 0 ? String.Join("", strings) : "An unspecified ICE plugin error has occurred.");
 }
Beispiel #8
0
 /// <summary>
 /// Joins all given parameters into one error message.
 /// </summary>
 /// <param name="exception">An optional exception object, or 'null' if none.</param>
 /// <param name="strings">The strings to use as a single error message.</param>
 public void SetErrorMessage(Exception innerException, params string[] strings)
 {
     _Error = ICEController.WriteICEEventError(strings.Length > 0 ? String.Join("", strings) : "An ICE plugin error has occurred.", innerException);
 }