예제 #1
0
        /// <summary>
        /// Function to catch and handle an exception.
        /// </summary>
        /// <typeparam name="T">The type of exception. This value must be or inherit from the <see cref="Exception"/> type.</typeparam>
        /// <param name="ex">Exception to pass to the handler.</param>
        /// <param name="handler">A method that is called to handle the exception.</param>
        /// <param name="log">[Optional] A logger that will capture the exception, or <b>null</b> to disable logging of this exception.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="ex"/> parameter is <b>null</b>.</exception>
        /// <remarks>
        /// This is a convenience method used to catch an exception and then handle it with the supplied <paramref name="handler"/> method. The handler method must take a parameter
        /// that has a type that is or derives from <see cref="Exception"/>.
        /// </remarks>
        public static void Catch <T>(this T ex, Action <T> handler, IGorgonLog log = null)
            where T : Exception
        {
            if ((ex == null) ||
                (handler == null))
            {
                return;
            }

            log?.LogException(ex);

            handler(ex);
        }
예제 #2
0
        /// <summary>Function to load all the specified plug in assemblies.</summary>
        /// <param name="pluginCache">The plugin cache that will hold the plug in assembies.</param>
        /// <param name="pluginAssemblyFiles">The list of plug in assembly paths to load.</param>
        /// <param name="log">The application logging interface.</param>
        /// <returns>A list of <see cref="PlugInAssemblyState"/> objects for each plug in assembly loaded.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="pluginAssemblyFiles" /> parameter is <b>null</b></exception>
        public static IReadOnlyList <PlugInAssemblyState> ValidateAndLoadAssemblies(this GorgonMefPlugInCache pluginCache, IEnumerable <FileInfo> pluginAssemblyFiles, IGorgonLog log)
        {
            if (pluginAssemblyFiles == null)
            {
                throw new ArgumentNullException(nameof(pluginAssemblyFiles));
            }

            var records = new List <PlugInAssemblyState>();

            // We use this to determine whether the plug in can be loaded into the current platform.
            AssemblyPlatformType currentPlatform = IntPtr.Size == 8 ? AssemblyPlatformType.x64 : AssemblyPlatformType.x86;

            foreach (FileInfo file in pluginAssemblyFiles)
            {
                // If we've already got the assembly loaded into this cache, then there's no need to try and load it.
                if (pluginCache.PlugInAssemblies?.Any(item => string.Equals(item, file.FullName, StringComparison.OrdinalIgnoreCase)) ?? false)
                {
                    continue;
                }

                if (!file.Exists)
                {
                    log.Print($"[ERROR] Plug in '{file.FullName}' was not found.", LoggingLevel.Verbose);
                    records.Add(new PlugInAssemblyState(file.FullName, Resources.GOREDIT_PLUGIN_LOAD_FAIL_NOT_FOUND, false));
                    continue;
                }

                (bool isManaged, AssemblyPlatformType platformType) = GorgonMefPlugInCache.IsManagedAssembly(file.FullName);

                if ((!isManaged) || (platformType == AssemblyPlatformType.Unknown))
                {
                    log.Print($"[WARNING] Skipping '{file.FullName}'. Not a valid .NET assembly.", LoggingLevel.Verbose);
                    records.Add(new PlugInAssemblyState(file.FullName, string.Format(Resources.GOREDIT_PLUGIN_LOAD_FAIL_NOT_DOT_NET, file.Name), false));
                    continue;
                }

                // Ensure that our platform type matches (AnyCPU is exempt and will always run, and DLLs don't allow Prefer 32 bit).
                if ((currentPlatform == AssemblyPlatformType.x86) && (platformType == AssemblyPlatformType.x64))
                {
                    log.Print($"[ERROR] Cannot load assembly '{file.FullName}', currently executing in an x86 environment, but the assembly is x64.", LoggingLevel.Simple);
                    records.Add(new PlugInAssemblyState(file.FullName, string.Format(Resources.GOREDIT_PLUGIN_LOAD_FAIL_PLATFORM_MISMATCH, file.Name, platformType, currentPlatform), true));
                    continue;
                }

                if ((currentPlatform == AssemblyPlatformType.x64) && (platformType == AssemblyPlatformType.x86))
                {
                    log.Print($"[ERROR] Cannot load assembly '{file.FullName}', currently executing in an x64 environment, but the assembly is x86.", LoggingLevel.Simple);
                    records.Add(new PlugInAssemblyState(file.FullName, string.Format(Resources.GOREDIT_PLUGIN_LOAD_FAIL_PLATFORM_MISMATCH, file.Name, platformType, currentPlatform), true));
                    continue;
                }

                try
                {
                    log.Print($"Loading plug in assembly '{file.FullName}'...", LoggingLevel.Simple);
                    pluginCache.LoadPlugInAssemblies(file.DirectoryName, file.Name);

                    records.Add(new PlugInAssemblyState(file.FullName, string.Empty, true));
                }
                catch (Exception ex)
                {
                    log.Print($"ERROR: Cannot load plug in assembly '{file.FullName}'.", LoggingLevel.Simple);
                    log.LogException(ex);
                    records.Add(new PlugInAssemblyState(file.FullName, string.Format(Resources.GOREDIT_PLUGIN_LOAD_FAIL_EXCEPTION, file.Name, ex.Message), true));
                }
            }

            return(records);
        }