【问题标题】:Loading Interface in DLL Dynamically动态加载DLL中的接口
【发布时间】:2013-06-28 22:52:02
【问题描述】:

我试图学习如何将 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!");
    }
  }
}

在我的主程序中,我尝试做这样的事情:

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();
}

我遇到的问题是,即使

type.FullName

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

线

myDll.CreateInstance(type.FullName) as Action

总是返回 null。

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

与示例一样,我希望能够将新的 Action 实现添加到 DLL,并让主程序在每个实现上调用 DoAction(),而无需重新编译原始程序。希望这是有道理的!

【问题讨论】:

  • 你在这里使用的Action,在as Action,它是在哪里定义的?您是使用第一段代码引用程序集,还是声明了两次 Action,一次在您从 TestDLL.dll 加载的程序集中,一次在您的主项目中?

标签: c# dll interface


【解决方案1】:

通过您的主要实现,您最好这样做

            List<object> actions = new List<object>();
            Assembly myDll = Assembly.LoadFrom("TestDLL.dll");
            Type[] types = myDll.GetTypes();

            for (int i = 0; i < types.Length; i++)
            {
                Type type = myDll.GetType(types[i].FullName);
                if (type.GetInterface("TestDLL.Action") != null)
                {
                    object obj = Activator.CreateInstance(type);
                    if (obj != null)
                        actions.Add(obj);
                }
            }

            foreach (var action in actions)
            {
                MethodInfo mi = action.GetType().GetMethod("DoAction");
                mi.Invoke(action, null);
            }

你应该把它包装在一个 try/catch 块中。 当您编写 Action 时(因为您没有设置对程序集的引用),例如在 List&lt;Action&gt; 中,此 Action 是指 Action 委托。

【讨论】:

    【解决方案2】:

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

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

    查看更多信息:Cannot get types by custom attributes across assemblies

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-07
      • 1970-01-01
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多