DI контейнер дает новый экземпляр каждый раз? - PullRequest
0 голосов
/ 26 сентября 2019

Кажется, мой 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>();
    }
}

1 Ответ

0 голосов
/ 27 сентября 2019

Вы создаете нового поставщика услуг каждый раз, когда вызывается Reusables.GetServiceProvider.Это каждый раз приводит к новому провайдеру, а каждый раз, когда новый провайдер получает услугу, - новый экземпляр.

Если цель состоит в том, чтобы иметь одного провайдера, то требуется одиночный.

public static class Reusables {
    public static IDependencyProvider DependencyProvider;

    private static Lazy<IServiceProvider> serviceProvider = 
        new Lazy<IServiceProvider>(() => DependencyProvider.BuildServiceProvider());

    public static IServiceProvider GetServiceProvider() {
        return serviceProvider.Value;
    }
}

Не большой поклонник вышеуказанного дизайна, но он должен работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...