예제 #1
0
        public bool TryLoad(string pluginName, out IWridoPlugin plugin)
        {
            if (!pluginName.StartsWith("wrido.plugin", StringComparison.InvariantCultureIgnoreCase))
            {
                _logger.Warning("{pluginName} is not a recognized plugin name", pluginName);
                plugin = default;
                return(false);
            }

            if (_pluginLoder.TryLoad(pluginName, out plugin))
            {
                _logger.Verbose("Plugin {pluginName} found by assembly loader", pluginName);
                return(true);
            }

            var workingDirectory = CreateWorkingDirectory();
            var downloaded       = TryDownloadNuget(workingDirectory, pluginName, out var nugetFile);

            if (!downloaded)
            {
                Directory.Delete(workingDirectory, true);
                _logger.Warning("Unable to load plugin {pluginName}", pluginName);
                return(false);
            }

            var nugetDirectory = Path.Combine(workingDirectory, pluginName);

            try
            {
                _logger.Debug("Extracting {nugetFile} to {nugetDirectory}", nugetFile, nugetDirectory);
                ZipFile.ExtractToDirectory(nugetFile, nugetDirectory);
            }
            catch (Exception e)
            {
                Directory.Delete(workingDirectory, true);
                _logger.Warning(e, "Unable to extract {nugetFile} to {nugetDirectory}", nugetFile, nugetDirectory);
                return(false);
            }

            var dllFiles      = Directory.GetFiles(nugetDirectory, "*.dll", SearchOption.AllDirectories).ToList();
            var pluginDllPath = FindCompatibleDll(dllFiles);

            if (string.IsNullOrWhiteSpace(pluginDllPath))
            {
                Directory.Delete(workingDirectory, true);
                _logger.Warning("Unable to find compatable version of {pluginName}", pluginName);
                return(false);
            }

            var targetDllPath = Path.Combine(_config.InstallDirectory, Path.GetFileName(pluginDllPath));

            _logger.Debug("Copying file {pluginDllPath} to {targetDllPath}", pluginDllPath, targetDllPath);
            File.Copy(pluginDllPath, targetDllPath);
            Directory.Delete(workingDirectory, true);
            return(_pluginLoder.TryLoad(pluginName, out plugin));
        }
예제 #2
0
        public bool TryLoad(string pluginName, out IWridoPlugin plugin)
        {
            plugin = default;

            var assemblyFiles = Directory
                                .GetFiles(_config.InstallDirectory)
                                .Where(f => f.EndsWith(".dll", StringComparison.OrdinalIgnoreCase));

            var exactMatch = assemblyFiles.FirstOrDefault(f => f.EndsWith($"{pluginName}.dll", StringComparison.InvariantCultureIgnoreCase));

            if (exactMatch == null)
            {
                return(false);
            }

            try
            {
                var pluginAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(exactMatch);
                var pluginTypes    = pluginAssembly.DefinedTypes
                                     .Where(t => t.ImplementedInterfaces.Contains(typeof(IWridoPlugin)))
                                     .Where(t => t.GetConstructors().Any(c => !c.GetParameters().Any()))
                                     .ToList();

                if (pluginTypes.Count == 0)
                {
                    _logger.Debug("Assembly {assemblyName} did not contain any matching wrido plugins", pluginAssembly.FullName);
                    return(false);
                }
                if (pluginTypes.Count != 1)
                {
                    _logger.Warning("Assembly {assemblyName} contains {pluginCount} plugins. Only one will be loaded. ", pluginAssembly.FullName, pluginTypes.Count);
                }
                var pluginType = pluginTypes.First();
                _logger.Information("Preparing to load plugin {pluginName} of type {pluginType} found in {pluginAssembly}", pluginName, pluginType, pluginAssembly.FullName);
                plugin = (IWridoPlugin)Activator.CreateInstance(pluginType);
                return(true);
            }
            catch (Exception e)
            {
                _logger.Warning(e, "Something went wrong when trying to create plugin {pluginName}", pluginName);
                return(false);
            }
        }