Кажется, мой DI-контейнер создает новый экземпляр для ChromeDriver (IWebDriver) каждый раз, когда я пытаюсь получить его из контейнера?Все это произошло после рефакторинга моего кода.Внезапно мне понадобился Selenium по ссылке для следующих методов, иначе он не будет обновлять DOM при загрузке новых страниц, так как я передавал его по значению.
Вот исходные методы перед рефакторингом,
public static bool ElementExists(IWebDriver selenium, By selector)
{
try
{
selenium.FindElement(selector);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
public static void WaitForElements(IWebDriver selenium, List<By> selectors, string name = "")
{
new ConsoleLogger().Trace("Waiting for " + (string.IsNullOrEmpty(name) ? selectors.Count + " items" : name) + ", give us a second.");
while (selectors.Where(x => ElementExists(selenium, x)).Count() < selectors.Count)
{
Thread.Sleep(100);
}
}
Я думал, хм, это будет сложно.Мне нужен был какой-то статический экземпляр, который я всегда мог передать по ссылке, я реорганизовал его в следующий класс:
public static bool ElementExists(By selector)
{
var selenium = Reusables.GetServiceProvider().GetService<IWebDriver>();
try
{
selenium.FindElement(selector);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
Класс многократного использования:
public static class Reusables
{
public static IDependencyProvider DependencyProvider;
public static IServiceProvider GetServiceProvider()
{
return DependencyProvider.BuildServiceProvider();
}
}
Программа:
private static void Main(string[] args)
{
var diProvider = new DependencyProvider();
Reusables.DependencyProvider = diProvider;
Console.ForegroundColor = ConsoleColor.White;
Console.CancelKeyPress += (sender, eArgs) => {
QuitEvent.Set();
eArgs.Cancel = true;
};
Console.WriteLine();
Console.CursorVisible = false;
/*var config = serviceProvider.GetService<IConfigProvider>();
config.Load("https://kskdkskd.kdskdkk", new WebClient());*/
var scraper = Reusables.GetServiceProvider().GetService<IScraperHandler>();
scraper.Start();
QuitEvent.WaitOne();
}
Не уверен, если это необходимо, но вот как я регистрирую свои зависимости:
public class DependencyProvider : ServiceCollection, IDependencyProvider
{
public DependencyProvider()
{
Register();
}
public void Register()
{
this.AddSingleton<IAuthProvider, AuthProvider>();
var options = new ChromeOptions();
options.AddArguments("--disable-notifications");
options.SetLoggingPreference(LogType.Browser, LogLevel.Off);
this.AddSingleton<IWebDriver>(provider =>
new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), options)
);
var links = File.ReadAllLines("***");
this.AddSingleton<IHttpHandler, HttpHandler>();
this.AddSingleton<IEnumerable>(stack => new Stack<string>(links.ToList()));
this.AddSingleton<IScraperHandler, ScraperHandler>();
this.AddSingleton<IConfigProvider, JsonConfigProvider>();
}
}