2009-11-23 5 views
1

В принципе, я хочу, чтобы иметь возможность писать DLL для моего приложения, что я могу разместить конкретную папку с использованием определенного имени, и во время выполнения она будет загружена и подписаться на конкретное событие. В качестве примера у меня есть простое приложение Windows Form с одной кнопкой на нем. Я хочу иметь сообщение MessageBox, отображаемое при событии нажатия кнопки, но я хочу, чтобы отображаемое сообщение контролировалось внешней dll, загружаемой во время выполнения. Что было бы лучшим способом добиться этого?Проводка событий из dll, загруженных во время выполнения?

ответ

3

Создать интерфейс, который включает в себя по крайней мере один метод для обработки события (приложение будет ссылаться на сборку, в которой это определено):

public interface IEventHandler { 
    void HandleEvent(object sender, EventArgs e); 
} 

Добавить класс в DLL вы хотите загрузить во время выполнения, который реализует интерфейс:

public class ConcreteEventHandler: IEventHandler { 
    public void HandleEvent(object sender, EventArgs e) { 
     // do something here 
    } 
} 

в приложении, используйте отражение, чтобы загрузить DLL и создать экземпляр вашего конкретного обработчика (проверка ошибок опущена):

// The assembly name/location could be configurable 
Assembly  assembly = Assembly.Load("MyAssembly.dll"); 
// The type name could be configurable 
Type   type  = assembly.GetType("ConcreteEventHandler"); 
IEventHandler handler = Activator.CreateInstance(type) as IEventHandler; 

Вы можете подключить этот обработчик до все, что вы хотите, например .:

MyButton.OnClick += handler.HandleEvent; 
+0

Спасибо. Когда я добираюсь до последней строки вашего образца кода, который я меняю с MyButton.OnClick + = handler.HandleEvent на MyButton.Click + = HandleEvent Я получаю сообщение об ошибке «Ссылка на объект, не установленное на экземпляр объекта» в этой строке. Что мне не хватает? – etoisarobot

+0

Вы можете проигнорировать приведенный выше комментарий относительно ошибки нулевой ссылки. Я скопировал dll в sep dir для импорта во время выполнения, а затем продолжил работу в Visual Studio, поэтому DLL, над которой я работал, не была dll, над которой работала. Duh. Благодарю. Вы, например, очень помогли. – etoisarobot

+0

Это одна из вечных ловушек загрузки «подключаемых» ассемблеров через отражение - если вы думаете о хорошем пути, сообщите нам об этом! :) Лучшее, что я могу порекомендовать, это добавить код для проверки всего и бросить очень специфические исключения, например: 'if (! File.Exists (assemblyPath)) {throw new FileNoteFoundException (string.Format (" Не удается найти сборку при {0 }. ", assemblyPath)); } '. (И добавьте что-то похожее для типа и т. Д.) –

0

Является ли DLL одной известной или вы будете загружать разные или несколько? Если последнее, я предлагаю изучить структуру AddIn в .NET 3.5.

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

Смежные вопросы