Send data back to .exe from dll - c#

I am developing a plug-in based application and need to be able to post data (strings, arrays) back to my main EXE when something happens. I'm not quite sure how to go about this, I have thought about creating a thread in the main application that would continuously call a method in the DLL asking for data but this seems very inefficient, is there some sort of event listener I could use for this?
Thanks.

As part of the loading mechanism for the plug-in DLLs, you could pass in a class object / function pointer / delegate / event that the DLL can use to inform the main application of any events the plug-in generates.

Instead of polling the DLL, you should consider using a form of Inversion of Control.
This can be as simple as exposing an event in the dll that your exe subscribes to, or passing in an object (or interface) to the DLL which it can use to call methods to notify your executable, etc. There are many options here, and its difficult to know the best without more information about your architecture.

You can use Delegates/Events on your DLL and subscribe with your EXE ?

Let's set some baselines...
EXE runs
EXE loads a DLL containing plugins
EXE instantiates a type (the "plugin")
Plugin starts waiting for an event
EXE waits
External event (on another thread) is noted by the plugin instance
EXE is notified of the event
If this is the case, the simplest thing is to define an event in your plugin type.
public interface IPlugin
{
public event EventHandler SomethingHappened;
public void StartWatchingForSomething();
}
where the code would be something like...
public static void Main()
{
foreach (var plugin in LoadAllPluginTypes()) // IoC container, MEF, something
{
plugin.SomethingHappened += SomethingHappenedEventHandler;
plugin.StartWatchingForSomething();
}
public void SomethingHappenedEventHandler(object sender, EventArgs e)
{
//derp
}
}
Please note, the event handlers are going to be firing on the same thread as the notification comes in on. For example, if your plugin is responding to file system events (via the FileSystemWatcher), the event handlers will be firing on the same thread as the thread that's executing code "defined in the dll".
If your EXE is a winforms or WPF project, you'll have to do an Invoke or Dispatcher.Invoke to get on the UI thread before updating any visual controls.

If it's a managed DLL (C# ,VB ,CLI/C++ with ref classes )
Reference the DLL in the project's references.
Right click on project -> Add reference -> Browse -> Choose the file.
After you do that you should get the API, and use it in a normal C# way.
The namespaces declared in the DLL will be accessible, and all the objects as well.

Related

Communication between two plugins in C#

I have two plugins that are running inside a third-party host application. The host application has an event called DocumentOpened that is raised when a document is opened.
Both plugins, Plugin A and Plugin B, are subscribing to this event. However, Plugin A and Plugin B do not know about each other, and they are executed independently.
Plugin A)
Host.DocumentOpened += SomeCodeA()
Plugin B)
Host.DocumentOpened += SomeCodeB()
What I want to achieve is to give control back to Plugin A after Plugin B has finished handling the DocumentOpened event. In other words, I want to call a method in Plugin A after Plugin B has finished executing.
To do this to do this you will probably need some way for Plugin A and B to communicate with each other. Here are some methods, but there is probably others:
EventWaitHandle
One fairly simple way would be with a system wide synchronization event. Both plugins would each create a EventWaitHandle with the same name. Plugin A could then create a thread that waits on the event, and Plugin B would set the event. If Plugin B does not exist then the event would never be raised. This is a system wide event, so would not work if multiple instances of the host is running, unless you do something like including the processor-id to the event name.
IPC/RPC methods
There are various ways for processes to communicate with each other that could be used:
Named pipes
Message buss
web service
Windows communication foundation
This would be a more complicated solution, but would also be more generic. It could for example handle if the host application decides to run plugins in separate processes, or if you want to transfer more data between the plugins.
Shared assembly
You could create an assembly that is used by both of your plugins. This would allow you to create a singleton object that is shared between both plugins. Something like this:
public class PluginCommunication
{
public event EventHandler MyEvent;
public void RaiseEvent() => MyEvent?.Invoke(this, EventArgs.Empty);
public static PluginCommunication PluginBEvent = new PluginCommunication();
}
plugin B would call PluginCommunication.PluginBEvent.RaiseEvent(); and plugin A would attach an event handler like PluginCommunication.PluginBEvent.MyEvent += PluginAEventHandler;
There are potential pitfalls with this method. if you need to change the assembly in any way you face the risk of plugin A using version 1 and plugin B using version 2, and that may end badly if you are not very careful. Threading issues might also occur if you do not do everything on the main thread.

architecture for bubbling events through classes hierarchy

I have a simple application that consists of a console application and a class library. The class library does all of the heavy lifting throughout its few-dozen classes. Some of those classes are internal to the class library, and even if public, I'd rather not have the console application completely aware of them.
So I could have something like:
My Program.cs class that is running.
My DoSomething.cs class that is being called by Program.cs.
My DoSomethingInParticular.cs class that is being called by DoSomething.cs
And so on, and so on.
Is there a generally understood way of letting Program.cs be aware of lower changes?
Functionally I'd like to have my console application write out lower level events to the console window, which is where I'm trying to go with this.
A module only knows as much as it knows.
I see 2.1 main paths for you.
1) Make public events in DoSomething that Program can listen to.
Make public events in DoSomethingInParticular that DoSomething can listen to.
When DoSomething receives an event it decides if it is proper for bubbling and transforms it to one event of its own and raises it for Program to receive.
1.1) Put the data carrying structures/classes in the events in another, common, lib. Then when an event is received DoSomething doesn't have to transform it but only decide whether to bubble it or not.
2) Make an event handling lib of its own to handle who receives what.
Without knowing more I would go with 1.1.
HTH

Can I Add a handler to AppDomain.CurrentDomain.UnhandledException in a class library

I want to subscribe to the AppDomain.CurrentDomain.UnhandledException event to catch any errors as im trying a new design pattern where I dont want to put a try catch on every event.
usually in a win forms app there is a main entry point, but this is a class library that is called by another application.
Is there a main entry point in a class library where I can hook up this event, or is it just not possible in a class library unless im sure one method will get called before anything else?
No, class libraries don't have a main entry point. If you feel like you need one, then you could conceptually create one virtually via your public API surface area. In other words, limit what objects are public and in those public objects make sure the call gets made at some point. That could be taken to the extreme of requiring a factory call of some kind to setup your library before doing anything.
// Set the unhandled exception mode to force errors to go through our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Thanks to Brian Dishaw
Clearly this does not give you some non declarative way of assigning the handler, ala assingning a trace listener in app.config but, that gives me an idea.
You could write your own configuration section that would perform this code. Then when the config is loaded you could assign the event handler, I'll find some links on how to do that ...
However, your configuration would have to be present in the main app so perhaps this is not right.
EDIT Sorry, I don't think there is way to do this without a IoC framework of some kind, what else would load your class. The only options I can think of all require some sort of change to the main application.
I'm interested in being wrong.

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.
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?
Make sure that your CallbackClass inherits from MarshalByRefObject. Otherwise, a copy of the callback class will be created on the other side of the appdomain boundary, making cross-appdomain communication impossible.

C# .NET events and multithreading

I am developing an application that is split into multiple .NET assemblies (one main executable and a set of class libraries). Currently, I am using a WPF GUI, but I need to maintain the flexibility to possibly switch to another GUI framework at a later time.
Here is my problem: one of the class libraries performs some work on a separate thread, and raises an event when that thread is complete. I quickly discovered that my WPF GUI got upset when I tried to modify its components from this event handler, so I implemented an "event queue" that dispatches events on the main thread using a System.Windows.Threading.DispatcherTimer. This did the job; however, I was horrified to discover that this DispatcherTimer only works within the context of a WPF application!
I am trying to hide all the ugly details of multithreading within this class library, which may eventually be used in conjunction with a non-WPF GUI. The idea is, the consuming application should be able to update its GUI from within the event handlers. So, my question is, is there a standard method (independent of any particular GUI framework) for raising events on a different thread??
Any help would be appreciated. Thanks.
You need to use ISyncronizeInvoke. This interface allows you to check if you are on the right thread, and if not, Invoke a method on the correct thread. I haven't done this in WPF, but I assume it is implemented there as well as Windows Forms.
Typically you would just marshal the event data to the main thread by reinvoking the event handler from the main thread. One method is shown below.
private void DispalyMessage(byte[] bytes)
{
if (this.InvokeRequired)
{
lock (_lock)
{
EventHandler d = new EventHandler(DispalyMessage);
this.Invoke(d, new object[] { bytes });
return;
}
}
else
{
//do something with the data
}
}
Enjoy!
You could use SynchronizationContext (which is what BackgroundWorker does, I believe) - or you could just warn your clients that the events will be raised on a background thread, and that they should perform whatever marshalling they need to (as other APIs like FileSystemWatcher do.)
Instead of events from the class library, use a callback method that your GUI code provides. Although the callback will be invoked on the library's thread, your GUI code can decide what's the best way to handle it. This should simplify switching to a different GUI.

Categories