Как к: автоматический инстанцируют Singleton в C#

Это напрямую не поддерживается ни в каких драйверах Capybara, о которых я знаю, однако вы можете подделать указатель мыши с помощью некоторого JS, как показано в Визуализация / показать положение курсора мыши в тестах на селен 2 (например, PHPUnit Webdriver) [ 113]

По сути, это сводится к созданию изображения, а затем перемещению его местоположения каждый раз, когда происходит событие mousemove

// Create mouse following image.
var seleniumFollowerImg = document.createElement("img");

// Set image properties.
seleniumFollowerImg.setAttribute('src', 'data:image/png;base64,'
    + 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAQAAACGG/bgAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAA'
    + 'HsYAAB7GAZEt8iwAAAAHdElNRQfgAwgMIwdxU/i7AAABZklEQVQ4y43TsU4UURSH8W+XmYwkS2I0'
    + '9CRKpKGhsvIJjG9giQmliHFZlkUIGnEF7KTiCagpsYHWhoTQaiUUxLixYZb5KAAZZhbunu7O/PKf'
    + 'e+fcA+/pqwb4DuximEqXhT4iI8dMpBWEsWsuGYdpZFttiLSSgTvhZ1W/SvfO1CvYdV1kPghV68a3'
    + '0zzUWZH5pBqEui7dnqlFmLoq0gxC1XfGZdoLal2kea8ahLoqKXNAJQBT2yJzwUTVt0bS6ANqy1ga'
    + 'VCEq/oVTtjji4hQVhhnlYBH4WIJV9vlkXLm+10R8oJb79Jl1j9UdazJRGpkrmNkSF9SOz2T71s7M'
    + 'SIfD2lmmfjGSRz3hK8l4w1P+bah/HJLN0sys2JSMZQB+jKo6KSc8vLlLn5ikzF4268Wg2+pPOWW6'
    + 'ONcpr3PrXy9VfS473M/D7H+TLmrqsXtOGctvxvMv2oVNP+Av0uHbzbxyJaywyUjx8TlnPY2YxqkD'
    + 'dAAAAABJRU5ErkJggg==');
seleniumFollowerImg.setAttribute('id', 'selenium_mouse_follower');
seleniumFollowerImg.setAttribute('style', 'position: absolute; z-index: 99999999999; pointer-events: none;');

// Add mouse follower to the web page.
document.body.appendChild(seleniumFollowerImg);
document.addEventListener('mousemove', function(e) {
  const mousePointer = document.getElementById('selenium_mouse_follower');
  mousePointer.style.left = e.pageX + 'px';
  mousePointer.style.top = e.pageY + 'px';
});

Затем вам необходимо убедиться, что JS выполняется после каждое изменение страницы (посещение, щелчок, который перемещается и т. д.). Есть много способов сделать это, при этом самым простым является либо условно добавить код в приложение в тестовом режиме, либо вызвать его вручную с помощью вспомогательного метода, вызывающего page.execute_js всякий раз, когда вы хотите, чтобы положение мыши отображалось для следующих действий. [ 116]

6
задан Jonathan Leffler 27 April 2009 в 22:33
поделиться

8 ответов

Упомянутый Крисом подход IoC, вероятно, является лучшим, но в случае неудачи «лучшее» решение, которое я могу придумать, состоит в том, чтобы сделать что-то прикольное с отражением и атрибутами в соответствии с: С вызовом InitOnLoad.Initialise (), добавленным в ваш метод main.

Вы можете покончить с атрибутом, но это может привести к инициализации ненужных типов и ненужному потреблению памяти (например, Bar в приведенном выше коде).

Стоит также отметить, что он не будет обрабатывать типы, содержащиеся в каких-либо сборках, которые загружаются динамически, если только вы не сделаете еще один вызов Initialise, но на основе вашего вопроса («автоматическое создание экземпляра при запуске программы»), который не похож на проблема для вас.

6
ответ дан 8 December 2019 в 12:22
поделиться

Хотя модули .NET теоретически (IIRC) могут реагировать на загрузку модулей и т. Д., Это не доступно через C #. В некоторых средах (например, ASP.NET) есть хуки, которые вы можете использовать через конфигурацию, например, взломать их через обработчик или через global.asax.cs - однако для обычного приложения на C # (console, winform и т. Д.) Вам придется вызвать его вручную. Например, статический конструктор класса, в котором находится точка входа Main , будет вызван.

Итак: каков здесь вариант использования? Когда не будет подход ленивой загрузки?

5
ответ дан 8 December 2019 в 12:22
поделиться

Я сомневаюсь, что это возможно, ничего не делая из Main . Даже добавление статического MySingleton () {} к классу не гарантирует его создания, если вы его не используете.

2
ответ дан 8 December 2019 в 12:22
поделиться

Вы в основном просите .NET Framework вызывать некоторую функцию всякий раз, когда она загружает сборку. Эта функция будет регистратором экземпляров PClass.

В C # нет DllMain . Вы можете смоделировать это, имея атрибут уровня сборки и некоторый код в вашем методе main, который прослушивает каждый раз, когда загружается сборка. Атрибут может иметь указанную точку входа « DllMain » или указывать на ваши унаследованные классы PCIass.

1
ответ дан 8 December 2019 в 12:22
поделиться

Исходя из того, что вы пытаетесь сделать, я бы отбросил идею истинного синглтона и вместо этого использовал бы библиотеку IoC.

Изучите StructureMap, Castle Windsor, Ninject и / или Autofac.

Это позволит вам создать класс как синглтон, с помощью библиотеки IoC, иметь столько, сколько вы хотите, но это просто старая класс.

У синглетонов есть проблема в том, что они действительно портят тестируемость (через модульное тестирование) вашего приложения.

Просто выполните поиск в Google по «Синглтону считается вредным», и вы увидите еще много ссылок.

Кроме того, вы также можете использовать простой шаблон фабрики классов / методов.

4
ответ дан 8 December 2019 в 12:22
поделиться

Я не верю, что то, что вы хотите, возможно в .Net framework. По сути, вы хотите, чтобы что-то вроде среды выполнения уведомляло типы или вызывало некоторый предопределенный статический метод для них, чтобы приложение загружалось и работало, или предоставляло такой механизм. Подумай о накладных расходах. Единственное, что обеспечивает среда выполнения, - это автоматический вызов основного метода ввода для вашей программы. Вот и все. Там вы можете настроить и инициализировать вещи, но в этом нет ничего автоматического. Вы все еще явно подключаетесь и делаете вызовы методов.

0
ответ дан 8 December 2019 в 12:22
поделиться

Тангенциально, позвольте мне указать, что на самом деле это не одноэлементный паттерн, поскольку он обычно реализуется. Вот нормальная (упрощенная) реализация в C # (не включая такие вещи, как безопасность потоков для краткости):

public sealed class Singleton
{
static readonly Singleton _instance = new Singleton();

// private ctor
Singleton() {}

 public static Singleton Instance
 {
  get { return _instance; }
 }
}

Эта строка из вашего кода даже не должна компилироваться!

protected MySingleton()

Сказав все это, я согласен с парнем, который спросил что касается вашего варианта использования. Это было бы полезно знать. =)

1
ответ дан 8 December 2019 в 12:22
поделиться

«У PClass будет статический элемент, представляющий собой коллекцию PClasses ...»

Звучит как то, что можно легко сделать с помощью Reflection. Вам не нужен код, который запускается при запуске; вы можете просто создать список этих классов, когда вам это нужно.

Вот пример, который загружает список один раз, когда вы впервые читаете свойство Instances, просматривает все сборки, загруженные в это время (вы могли бы упростить это немного, если вы хотите посмотреть только в той же сборке, что и PClass, но ваш вопрос не указывает, в каких сборках вы хотите искать), и добавит один экземпляр любого потомка PClass (но не самого PClass) к список. Каждому потомку PClass понадобится конструктор без параметров, но вам не понадобятся конструкторы классов.

public class PClass
{
    private static List<PClass> m_instances;
    public static IList<PClass> Instances
    {
        get
        {
            if (m_instances == null)
                m_instances = LoadInstanceList();
            return m_instances;
        }
    }
    private static List<PClass> LoadInstanceList()
    {
        foreach (var assembly in AppDomain.GetAssemblies())
        {
            foreach (var type in assembly.GetTypes())
            {
                if (type.IsAssignableTo(typeof(PClass)) && type != typeof(PClass))
                    m_instances.Add(Activator.CreateInstance(type));
            }
        }
    }
}
0
ответ дан 8 December 2019 в 12:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: