我正在尝试学习如何将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(),而不必重新编译原始程序。希望这有道理!
您很可能Action是在主程序集和“其他”程序集中定义的,并且您正在转换到错误的程序集。
通常共享接口在单独的程序集(“SDK”)中定义,并从主应用程序和插件程序集链接。通过源共享接口不起作用,因为类的标识包括程序集名称和类型名称。
请参阅参考资料以获取更多信息:无法通过程序集的自定义属性获取类型