private void LoadAndExecute(string scraper, CancellationToken cancelationToken) { var context = new ScraperLoadContext(); try { _logger.LogInformation("Starting scraper {scraper}", scraper); var path = Path.Combine(Directory.GetCurrentDirectory(), "Scrapers", $"{scraper}.dll"); var assembly = context.LoadFromAssemblyPath(path); var type = assembly.GetType($"{scraper}.Scraper"); var method = type.GetMethod("ExecuteAsync"); var instance = ActivatorUtilities.CreateInstance(_serviceProvider, type); _queue.ScraperStatusChanged(scraper, CurrentStatus.Running); var task = (Task <ScrapingResult>)method.Invoke(instance, new object[] { _browserService.Browser, cancelationToken }); switch (task.Result) { case ScrapingResult.Success: _queue.ScraperStatusChanged(scraper, CurrentStatus.Success); break; case ScrapingResult.Canceled: _queue.ScraperStatusChanged(scraper, CurrentStatus.Canceled); break; case ScrapingResult.Error: _queue.ScraperStatusChanged(scraper, CurrentStatus.Error); break; default: _queue.ScraperStatusChanged(scraper, CurrentStatus.Unknown); break; } _logger.LogInformation("Scraper {scraper} finished", scraper); } catch (Exception exc) { _queue.ScraperStatusChanged(scraper, CurrentStatus.Error); _logger.LogError(exc, "Scraper {scraper} error", scraper); } //TODO: https://developercommunity.visualstudio.com/content/problem/785136/c-debugger-crashes-after-unloading-assemblyloadcon.html context.Unload(); }
private ScraperValidateResult ValidateScraper(string path) { var result = new ScraperValidateResult { Parameters = new List <Parameter>() }; var context = new ScraperLoadContext(); var assembly = context.LoadFromAssemblyPath(path); var bytes = assembly.GetName().GetPublicKeyToken(); if (bytes != null && bytes.Length > 0) { var token = BitConverter.ToString(bytes).Replace("-", string.Empty).ToLower(); if (token == "b96cd5d24947157a") { var name = Path.GetFileNameWithoutExtension(path); var type = assembly.GetType($"{name}.Scraper"); var instance = ActivatorUtilities.CreateInstance(_provider, type); result.Description = type.GetProperty("Description").GetValue(instance, null).ToString(); var resourceNames = assembly.GetManifestResourceNames(); foreach (var rn in resourceNames) { using var stream = assembly.GetManifestResourceStream(rn); using var reader = new StreamReader(stream, Encoding.UTF8); result.Parameters.Add(new Parameter { Name = rn, Value = reader.ReadToEnd() }); } result.Success = true; } } context.Unload(); return(result); }