2

I want to call a method, which is in my program from my dll.
I now I can add an argument public void Bar(Action<string> print, string a). But is there other way to call it?
code in dll:

class Foo {
    public void Bar(string a) {
        //now I want to call method from program
        Program.Print(a); // doesn't work
    }
}

program:

class Program {
    public static void Main(string[] args) {
        var dll = Assembly.LoadFile(@"my dll");
        foreach(Type type in dll.GetExportedTypes())
        {
            dynamic c = Activator.CreateInstance(type);
            c.Bar(@"Hello");
        }
        Console.ReadLine();
    }
    public static void Print(string s) {
        Console.WriteLine(s);
    }
}

from (Loading DLLs at runtime in C#)
Is it possible?

galaxy001
  • 404
  • 5
  • 16
  • Did you mean `MyProgram` or `Program`? What do you mean "doesn't work"? – John Wu Sep 28 '19 at 06:31
  • @JohnWu I meant `Program`. I meant it shows error _The name Program doesn't exist in curcurent content._ with "doesn't work". – galaxy001 Sep 28 '19 at 07:13
  • 2
    The DLL can only be built after you built your main project. While that is technically possible, it is something you strongly want to avoid. Use an interface to expose host services to a plugin. – Hans Passant Sep 28 '19 at 08:14
  • I agree with @HansPassant. If you're building out a pluggable architecture, you will need an orderly way to expose services to the plugins. [Inject](https://stackoverflow.com/questions/130794/what-is-dependency-injection) an `IPluginContext` or something, and give it a `Print` method. – John Wu Sep 28 '19 at 08:33

3 Answers3

2

You can use a callback.

You add an event in the dll.

From the program you assign the event.

So from the dll, you can call the event.

Put in a public class in the dll:

public event EventHandler MyCallback;

From the program set it to desired method:

MyDllClassInstance.MyCallback = TheMethod;

And now from the dll class you can write:

if (MyCallback != null) MyCallback(sender, e);

You can use any predefined event handler or create your own.

For example for your dll code:

public delegate PrintHandler(string s);

public event PrintHandler MyCallback;

public void Bar(string s)
{
  if (MyCallback != null) MyCallback(s);
}

So in the program you can put:

class Program {
  public static void Main(string[] args) {
      var dll = Assembly.LoadFile(@"my dll");
      foreach(Type type in dll.GetExportedTypes())
      {
          dynamic c = Activator.CreateInstance(type);
          c.MyCallback = Print;
          c.Bar(@"Hello");
      }
      Console.ReadLine();
  }
  public static void Print(string s) {
      Console.WriteLine(s);
  }
}

You can use Action<string> instead of defining a PrintHandler delegate.

0

In DLL, I added a reference to program, and that code works now.
code in dll:

class Foo {
    public void Bar(string a) {
        Program.Print(a);
    }
}

program:

class Program {
    public static void Main(string[] args) {
        var dll = Assembly.LoadFile(@"my dll");
        foreach(Type type in dll.GetExportedTypes())
        {
            dynamic c = Activator.CreateInstance(type);
            c.Bar(@"Hello");
        }
        Console.ReadLine();
    }
    public static void Print(string s) {
        Console.WriteLine(s);
    }
}
galaxy001
  • 404
  • 5
  • 16
-1

You may use reflection for it.

  1. Find type you need to use
  2. Find it's static method you want to call
  3. Invoke the method with an argument

See this website

misticos
  • 718
  • 5
  • 22