动态加载DLL中的接口

how*_*lee 5 c# dll interface

我正在尝试学习如何将DLL动态加载到C#程序中。这个想法是DLL将包含一个接口和该接口的几个不同实现,因此,如果我想添加新的实现,则不必重新编译整个项目。

所以我创建了这个测试。这是我的DLL文件:

namespace TestDLL
{
  public interface Action
  {
    void DoAction();
  }

  public class PrintString : Action
  {
    public void DoAction()
    {
      Console.WriteLine("Hello World!");
    }
  }

  public class PrintInt : Action
  {
    public void DoAction()
    {
      Console.WriteLine("Hello 1!");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在我的主程序中,我尝试执行以下操作:

static void Main(string[] args)
{
  List<Action> actions = new List<Action>();
  Assembly myDll = Assembly.LoadFrom("TestDLL.dll");
  Type[] types = myDll.GetExportedTypes();

  for (int i = 0; i < types.Length; i++)
  {
    Type type = types[i];
    if (type.GetInterface("TestDLL.Action") != null  && type != null)
    {
        Action new_action = myDll.CreateInstance(type.FullName) as Action;
        if (new_action != null)
          actions.Add(new_action);
        else
          Console.WriteLine("New Action is NULL");
    }
  }

  foreach (Action action in actions)
    action.DoAction();
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,即使

type.FullName
Run Code Online (Sandbox Code Playgroud)

包含正确的值(“ TestDLL.PrintString”等),

线

myDll.CreateInstance(type.FullName) as Action
Run Code Online (Sandbox Code Playgroud)

始终返回null。

我不确定是什么问题,或者如何解决。

如示例中所示,我希望能够将Action的新实现添加到DLL,并使主程序在每个实现上都调用DoAction(),而不必重新编译原始程序。希望这有道理!

Ale*_*kov 3

您很可能Action是在主程序集和“其他”程序集中定义的,并且您正在转换到错误的程序集。

通常共享接口在单独的程序集(“SDK”)中定义,并从主应用程序和插件程序集链接。通过源共享接口不起作用,因为类的标识包括程序集名称和类型名称。

请参阅参考资料以获取更多信息:无法通过程序集的自定义属性获取类型