Как удалить предыдущую версию события после изменения DLL во время выполнения? - PullRequest
0 голосов
/ 18 февраля 2019

Я использую приложение, позволяющее вставлять фрагменты кода c # в базу данных и компилировать их в DLL, которая перезагружается во время выполнения приложения.Я расширяю приложение, чтобы на настраиваемых сочетаниях клавиш отображалось окно поиска.

Почти все работает нормально, событие регистрируется и запускается правильно с первого раза, окно поиска работает.

Моя проблема возникает из-за событий KeyHandler между перекомпиляциями DLL (которые могут быть инициированы либо мной, либо другим пользователем, вносящим изменения в базу данных).

Как я могунайти ранее зарегистрированный обработчик KeyDown и удалить его?

Общий процесс

  1. Загрузка приложения
  2. Вставка пользовательского фрагмента и компиляция в DLL с уникальным именем
  3. Изменение пользовательского фрагмента во время выполнения
  4. Приложение обнаруживает изменение и DLL перекомпилируется с новым именем

Имя файла DLL основано на контрольной сумме, поэтому оно будет измененодаже если комментарии добавлены, и у меня нет никакого контроля над этим.

Код для создания элемента управления и добавления обработчика KeyDown, вызываемого один раз для компиляции

public class InitApp {        
    public void InitKeyBinding() {
        MainForm activeForm = AppManager.DialogParent;

        var controls = activeForm.Controls.Find("SearchBox", false);
        foreach (Control ctrl in controls) {
            ctrl.Dispose();
        }

        AutoCompleteTextBox txt_Search = new AutoCompleteTextBox();

        activeForm.KeyPreview = true;
        activeForm.KeyDown -= AllegroSearchBox.OpenSearchBox;
        activeForm.KeyDown += AllegroSearchBox.OpenSearchBox;

        return void;
    }
}

Код, который показывает поле на основеправильный ярлык, вызываемый при каждом событии KeyDown

public static class SearchBox {
    public static void OpenSearchBox(object sender, KeyEventArgs e) {
        MainForm activeForm = AppManager.DialogParent;
        if (e.Control && e.Shift && e.KeyCode == Keys.N) {  
            var controls = activeForm.Controls.Find("SearchBox", false);
            if (controls.Any()) {
                ((AutoCompleteTextBox)controls.First()).SetAllVisible();
            }
            e.Handled = true;
        }
    }
}

public class AutoCompleteTextBox : TextBox {
    public AutoCompleteTextBox() {
        MainForm activeForm = AppManager.DialogParent;
        this.Name = "SearchBox";
        this.Visible = false;
        this.Width = 400;            
        activeForm.Controls.Add(this);
    }
    public void SetAllVisible() {
        this.Visible = true;
    }
}

Приведение элемента управления к AutoCompleteTextBox вызывает проблемы.

Поскольку и AutoCompleteTextBox, и класс SearchBox, которые были зарегистрированы при начальной загрузке приложения (версия DLL [A]), больше не существуют, отмена регистрации события не удалась.И второе событие теперь регистрируется в новой версии классов (версия DLL [B]).

Сообщение об ошибке

    [A]AutoCompleteTextBox cannot be cast to [B]AutoCompleteTextBox.
    Type A originates from 'b6s6ARS1_6wG6Gt_XkVoWeh5a1u8ea7JSZp9bfTQ78Q, 
    Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
    in the context 'LoadFrom' at location 
    'C:\db06\Bin\b6s6ARS1_6wG6Gt_XkVoWeh5a1u8ea7JSZp9bfTQ78Q.dll'. 
    Type B originates from 'oYka1c8YhqEFWWFpX4TJFcd+f8sz15riYKSJVnKAkn0,
    Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' 
    in the context 'LoadFrom' at location 
    'C:\db06\Bin\oYka1c8YhqEFWWFpX4TJFcd+f8sz15riYKSJVnKAkn0.dll'.

Метод OpenSearchBox теперь вызывается 2 раза, первыйгенерирует указанное выше исключение, а второе работает нормально.При каждой дополнительной перекомпиляции он будет ломать текущий KeyHandler и добавлять новый.

Я смог скрыть проблему, добавив попытку catch вокруг явного приведения, но это неоптимальныйрешение!Кроме того, в качестве AutoCompleteTextBox используется controls.First (), который возвращает значение null, поскольку предыдущая версия класса больше не существует.

Я действительно хотел бы удалить старый обработчик, а не пытаться / ловить или проверять ноль вокруг него.

Большое спасибо за любые предложения, включая редизайн:)

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