Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What ways can I send data from a plugin across an app domain that triggers an event in the main application in C#?

I have a main application that loads up some plugins. These plugins are loaded and run in separate app domains using a class that inherits from "MarshalByRefObject"; This all works fine.

What I need now is a way to handle when the plugin wants the main app to do something and a way to dynamically handle this in the main application. If the best way is to poll the plugin for a list of commands, then I can do that, although it seems a bit of a kludge.

What are the best ways to send a request from the plugin across the app domain to the main app?

UPDATE

As an update to the question, I am looking to sent data across the app domain that makes the main app do something, like a "File->New" operation or "GetSomeData()" call. In doing this I need to make the Plugin wait for the main app to complete whatever it is doing, but also be able to decide, main app side, whether or not to execute the requested function/event.

I was doing this by passing the plugin an interface. This interface was implemented by a class in the main app that defined some events. The main app could then subscribe to these events and the plugin could make the main app functions fire. The problem is that the interface only referenced the class as it was when I passed the interface. I.e if I created the class with no events subscribed, then passed the interface like this:

CallbackClass myCallbackClass = new CallbackClass();
pluginInterface.HeresMyCallbackClass((ICallbackClass)myCallbackClass);

the plugin would receive the interface, but any changes to the original class did not propagate. So adding:

myCallbackClass.MyMainAppEvent += new MainEventHandler(MyMainAppFunction);

would not change the plugin's version of the event. The plugin could do this:

//code within plugin
ICallbackClass callToMainApp;
public HeresMyCallbackClass(ICallbackClass cbClass)
{
    callToMainApp = cbClass;
}

public CallAMainAppFunction()
{
    callToMainApp.CallTheSubscribedFunction(); //This is where it all goes wrong
}

...but the event that it tries to call is null. Now, this is not a problem if I make the main app subscribe to the event first, then pass the interface:

CallbackClass myCallbackClass = new CallbackClass();
myCallbackClass.MyMainAppEvent += new MainEventHandler(MyMainAppFunction); //Subscribe first
pluginInterface.HeresMyCallbackClass((ICallbackClass)myCallbackClass);

The plugin could then call CallTheSubscribedFunction() and the event would fire in the main app. I need to be able to subscribe to events like this on demand because some things/events/data in the main app are available at different times.

So, a lot of info I was trying to avoid having to write out, but I guess my question was too general in relation to my issue.

If anyone has suggestions please let me know. Again, my goal is to allow the plugin to trigger an event in the main app, wait for the main app to finish, then continue with it's execution, where the main app may or may not be subscribed to the events.

Update 2

I realize the above info is specialized to my application, but I'm looking for general suggestions as well. So, if using threads is an option, let me know how a general case might work. If another case would work better and I need to do some redesigning to implement it let me know that as well. Just looking for suggestions here. Thanks.

like image 459
Mike Webb Avatar asked Nov 15 '22 03:11

Mike Webb


1 Answers

Mike from the looks of it, you're sort of already what what I think is required and that you should use the Observer Pattern between the class in your primary app domain and the secondary app domain.

You probably just need to iron out the some rough edges in the code you've got, in word words follow/implement the observer pattern.

The way it would work is that the class in the primary domain subscribes to "events" that the class that's been loaded in the secondary app domain raises. I'm guessing that you'll need to do this at the time the secondary app domain classes is instantiated. If you're unloading the app domain, then also make sure of "subscriptions" are "disconnected".

Does that make sense?

like image 152
Shiv Kumar Avatar answered Dec 06 '22 08:12

Shiv Kumar