Beispiel #1
0
        public PluginContainer GetPlugin(string path, ILogger logger)
        {
            var loadContext = new PluginLoadContext(Path.GetFileNameWithoutExtension(path) + "LoadContext", path);
            var assembly    = loadContext.LoadFromAssemblyPath(path);

            return(HandlePlugin(loadContext, assembly, path, logger));
        }
Beispiel #2
0
        internal PluginContainer HandlePlugin(PluginLoadContext loadContext, Assembly assembly, string path, ILogger logger)
        {
            Type pluginType = assembly.GetTypes().FirstOrDefault(type => type.IsSubclassOf(typeof(PluginBase)));

            PluginBase plugin;

            if (pluginType == null || pluginType.GetConstructor(Array.Empty <Type>()) == null)
            {
                plugin = default;
                logger?.LogError("Loaded assembly contains no type implementing PluginBase with public parameterless constructor.");
                return(new PluginContainer(new PluginInfo(Path.GetFileNameWithoutExtension(path)), path));
            }
            else
            {
                logger?.LogInformation("Creating plugin instance...");
                plugin = (PluginBase)Activator.CreateInstance(pluginType);
            }

            string name      = assembly.GetName().Name;
            var    attribute = pluginType.GetCustomAttribute <PluginAttribute>();
            var    info      = attribute != null ? new PluginInfo(name, attribute) : new PluginInfo(name);

            if (attribute == null)
            {
                logger?.LogWarning($"Plugin is missing {nameof(PluginAttribute)}. Name defaults to '{info.Name}', version defaults to {info.Version}.");
            }

            return(new PluginContainer(plugin, info, assembly, loadContext, path));
        }
        public PluginContainer GetPlugin(string path, ILogger logger)
        {
            string name = Path.GetFileNameWithoutExtension(path);

            FileStream fileStream;

            try
            {
                fileStream = File.OpenRead(path);
            }
            catch
            {
                logger.LogError($"Reloading '{Path.GetFileName(path)}' failed, file is not accessible.");
                return(new PluginContainer(new PluginInfo(name), name));
            }
            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(SourceText.From(fileStream));

            fileStream.Dispose();
            var compilation = CSharpCompilation.Create(name,
                                                       new[] { syntaxTree },
                                                       MetadataReferences,
                                                       CompilationOptions);

            using var memoryStream = new MemoryStream();
            EmitResult emitResult = compilation.Emit(memoryStream);

            if (!emitResult.Success)
            {
                if (logger != null)
                {
                    foreach (var diagnostic in emitResult.Diagnostics)
                    {
                        if (diagnostic.Severity != DiagnosticSeverity.Error || diagnostic.IsWarningAsError)
                        {
                            continue;
                        }

                        logger.LogError($"Compilation failed: {diagnostic.Location} {diagnostic.GetMessage()}");
                    }
                }

                return(new PluginContainer(new PluginInfo(name), name));
            }
            else
            {
                memoryStream.Seek(0, SeekOrigin.Begin);

                var loadContext = new PluginLoadContext(name + "LoadContext", path);
                var assembly    = loadContext.LoadFromStream(memoryStream);
                return(PluginProviderSelector.CompiledPluginProvider.HandlePlugin(loadContext, assembly, path, logger));
            }
        }