Search code examples
c#functiondllcall

How to call a function of a class from another dll without knowing the class?


The project I am currently working on (reduced to this problem) consists of 3 parts:

    - A server class
    - An interface
    - Plugins that implement the interface

Now I want to send a message from a plugin, which is loaded as DLL via Reflection in the server project, to a connected client. Of course I need a function in my server class to send my message. Now the question is how to call this function from my plugin which only knows the interface without the possibility to get the singleton instantiation of the server class.

Theoretically I would say, I set an empty function pointer in the interface, which I then, when loading the plugin, let point to my method, via which I then send the message to the client. The only thing I found are delegates, which cannot be defined in the interface. So what would be an alternative?

Below a pseudocode for illustration. I hope you understand what I would like to do and can get me on the way to a solution. It is important that the plugins don't know any functions about the server, only the SendMessage method.

Pseudocode:

public class Server{
    private List<Plugin> mPlugins = new List<Plugin>();

    public Server() {
        LoadPlugins();
    }

    public void SendMessage(string message) {
        // Here I would send my message to some client
    }

    private void LoadPlugins() {
        // Here I'm loading my plugins (*.dll) from a specific folder into my mPlugins list

        // And while I'm looping through my plugins and loading them, I would set the function pointer to SendMessage(); Like:
        plugin.SendMyMessage = SendMessage;
    }
}

public interface SomeAPI {
    string Name {get;set;}
    string Version {get;set;}

    delegate void SendMyMessage(string message);
}

public class SomePlugin : SomeAPI {
    public string Name {get;set;} = "Some plugin";
    public string Version {get;set;} = "v1.0.0";

    void SendMessage(string message) {
        SendMyMessage(message);
    }
}

Solution

  • There are many ways to get callbacks from the plugin (if i understand you correctly)

    Why not just use and Events, Actions or Funcs

    public class ISomething
    {
       public Action<string,ISomething> MyCallBack { get; set; }
    }
    
    public class Server
    {
       private List<ISomething> mPlugins = new List<ISomething>();
    
       public Server()
       {
          LoadPlugins();
       }
    
       private void LoadPlugins()
       {
          foreach (var plugin in mPlugins)
             plugin.MyCallBack += MyCallBack;
       }
    
       private void MyCallBack(string message, ISomething plugin)
       {
          Console.WriteLine(message);
       }
    }