我正在构建一个小插件架构(遗憾的是MEF不是一个选项,因为它需要在.NET 2.0上运行)。 我希望能够将dll放在一个目录中,而无需重新编译主项目。 我的主要项目是一个winforms应用程序,它有一些对话框可以选择主程序所需的接口实现。
我有一个搜索某个目录的方法,并提供了我想要搜索实现该接口的类型的dll的位置列表。
public List<Type> GetPluginTypes()
{
List<Type> types = new List<Type>();
foreach (string dll in this.Plugins)
{
Assembly assembly;
try
{
assembly = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(dll));
}
catch
{
continue;
}
foreach (Type type in assembly.GetExportedTypes())
{
if (type.IsInterface || type.IsAbstract)
continue;
if (typeof(IMyInterface).IsAssignableFrom(type))
types.Add(type);
}
}
return types;
}
使用此方法,我向用户显示一个实现列表,选择一个,并将AssemblyQualifiedName保存到设置文件中。
当我启动主应用程序时,我从设置加载AQN并通过调用上述方法将所有插件加载到AppDomain中。
string typeName = GetSetting("MyPlugin");
GetPluginTypes(); // just to load the plugins into the app domain
Type.GetType(typeName); // allways returns null.
这是我的问题:Type.GetType(typeName),总是返回null。
我使用Type.GetType(typeName,true)来强制执行异常,我得到了: 无法加载文件或程序集“MyImpl,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null”或其依赖项之一。系统找不到指定的文件。“:”MyImpl,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null“}
我很无能为力。我已经将程序集加载到AppDomain中了,当我指定AQN时,仍然无法找到Type.GetType(string)。
答案 0 :(得分:3)
这可以通过为AppDomain注册AppDomain.AssemblyResolve
事件来解决,该事件将请求程序集并使处理程序返回已经加载的程序集。
这是处理程序在C#中的样子:
private System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
return
AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(Kandidaat => string.Equals(Kandidaat.GetName().FullName, args.Name));
}
详细说明可以在这里找到: https://msdn.microsoft.com/en-us//library/ff527268(v=vs.110).aspx
答案 1 :(得分:1)
也许这是相关的。来自Type.GetType(String, Boolean)的文档:
如果typeName仅包含名称 Type,此方法在中搜索 调用对象的程序集,然后在 mscorlib.dll程序集。如果typeName是 完全符合部分或 完整的程序集名称,此方法 在指定的程序集中搜索。
您说您尝试使用type.AssemblyQualifiedName
进行呼叫,但失败了。您是否检查了合格的名称以确定它是否合理?