Зачем использовать делегаты при использовании удаленного взаимодействия объектов MarshalByRefObj? - PullRequest
0 голосов
/ 11 ноября 2018

Мое приложение поддерживает плагины, у меня есть класс Core (MarshalByRefObj), который плагины должны наследовать, и этот класс предлагает различные функциональные возможности.Теперь мой вопрос: когда этот класс создается в главном домене приложения и передается плагину в другом домене приложения, какая польза от использования делегатов в таком сценарии:

public class Core : MarshalByRefObject
{
    public void DoSomething()
    {
         MyMainApp.Delegate1("SomeMethod", "Test");
    }
}

Итак, как вы можете видетьмой основной класс вызывает метод делегата MyMainApp.Я мог бы также просто сделать MyMainApp.SomeMethod("test").

Однако во многих онлайн-примерах о том, как работает система удаленного взаимодействия и плагинов, каждый, похоже, использует делегатов.Есть ли какая-то конкретная причина для этого?Может ли кто-нибудь дать мне более практичный пример того, почему?

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Одним из преимуществ будет то, что информация, передаваемая на MyMainApp.Delegate1, сериализуется для передачи из домена приложения плагина в домен главного приложения. Метод Delegate1 выполнит DoSomething в основном домене. Они не разделяют память (поэтому прямой доступ к экземплярам объекта невозможен). Таким образом, вы можете динамически запускать методы на других доменах приложений. И если это делается с помощью рефлексии, плагин может запускать не перечисленные методы.

Я бы предпочел не использовать этот тип конструкции, потому что нет никакой проверки во время компиляции вызывающих методов. Я бы предпочел использовать интерфейсы, которые есть в спутниковых сборках. (чтобы основной домен приложения не получал ссылку на / загрузку сборки плагина, чтобы он больше не мог выгружаться)


Другое дело: Если вы позвоните MyMainApp.SomeMethod("test") напрямую. Это означает, что плагин должен знать определение загрузчика плагинов. Это означает, что вы получаете жесткую связь (из плагина) с «родительским» приложением (версией). Что делает всю структуру плагина «бесполезной». Вы можете исправить это, внедрив интерфейс ISupportSomeMethod в MyMainApp, который определен в спутниковой сборке, используемой обоими mainapp и плагином. Если ваш MyMainApp не поддерживает интерфейс ISupportSomeMethod, плагин не совместим с этой программой. Таким образом, ваш MyMainApp может поддерживать несколько структур плагинов.


В этом случае вы предпочитаете структуру событий. Потому что дочерний объект хочет вызвать метод своего родителя. Жаль, что вызовы междоменных событий бесполезны, потому что ваш основной модуль загрузит сборку, и она не может быть выгружена. Вы можете написать прокси-класс для этого.

0 голосов
/ 11 ноября 2018

Большую часть времени элементы управления в пользовательском интерфейсе создаются основным потоком, если вы не намеренно создаете их в другом потоке.Вот важный бит: ТОЛЬКО поток, создавший элемент управления, может получить доступ к этому элементу управления.

Если вы вызываете DoSomething напрямую, а код в DoSomething хочет взаимодействовать с пользовательским интерфейсомконтроль, это не будет разрешено, и вы получите исключение.MyMainApp.Delegate1("DoSomething" эквивалентно: Пожалуйста, выполните указанный метод в главном потоке. Теперь он может получить доступ к элементам управления пользовательского интерфейса.

Есть и другие причины, но это самый важный бит, который нужно запомнить,Подробнее см. MSDN .

...