如何从另一个文件夹中加载的程序集中获取类型?
我使用以下代码:
Assembly.LoadFile("the assembly in another folder"); var type = Type.GetType("the full name of the type");
即使程序集已经在这行代码之前加载,它总是在type
返回null。
PS:我确实传递了程序集限定名,包括名称空间,类型名称,程序集名称,版本和公共令牌。
Type.GetType
仅搜索调用程序集中的类型和mscorlib.dll中的类型,除非您传递该类型的程序集限定名称。 看这里。
编辑
似乎Type.GetType
只能从Load上下文中的程序集中检索Type
实例。 使用LoadFile
加载的程序集不在上下文中 ,使用LoadFrom
加载的程序集位于Load From上下文中; 这些上下文都不允许您使用Type.GetType
因此分辨率将失败。 本文显示,当它所在的目录作为探测私有路径添加时,可以为程序集检索Type
信息,因为它将最终在Load上下文中,但在其他上下文中将失败。
“正确”(MS推荐)这样做的方法,当你必须对不在加载上下文但在load-from或no-context上下文中的程序集中的类型使用Type.GetType(string)
时,将绑定到Appdomain.AssemblyResolve
事件。 以下代码相对有效:
// this resolver works as long as the assembly is already loaded // with LoadFile/LoadFrom or Load(string) / Load(byte[]) private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) { var asm = (from a in AppDomain.CurrentDomain.GetAssemblies() where a.GetName().FullName == args.Name select a).FirstOrDefault(); if(asm == null) throw FileNotFoundException(args.Name); // this becomes inner exc return asm; } // place this somewhere in the beginning of your app: AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
创建AssemblyLoad / Resolve事件的组合以保留已加载程序集的字典(使用程序集名称作为键)似乎更有效。
在Assembly.LoadFile上
使用这种方法有一些严重的缺点。 根据MSDN :
LoadFile不会将文件加载到LoadFrom上下文中,也不会像LoadFrom方法那样使用加载路径解析依赖关系。
因此,如果可能,请不要使用LoadFile。 生成的程序集在无上下文上下文中加载,这比load-from上下文有更多的缺点。 相反,使用Assembly.LoadFrom和依赖项将从加载路径自动加载。
最简单的方法是简单地将Assembly.LoadFile的返回值捕获到变量中,并在其上调用GetType,如下所示:
Assembly assem = Assembly.LoadFile("assemblyLocation"); assem.GetType("typeName");
如果您希望经常从中提取类型,或者执行其他人建议的操作,并且创建循环遍历所有已加载程序集的更通用方法,您可能需要考虑保留对此程序集的引用。
你可以尝试这个….
Assembly.GetAssembly假定您有一个类型的实例,Type.GetType假定您具有包含程序集名称的完全限定类型名称。
你可以给出assembly所在的路径…..
如果您只有基本类型名称,则需要执行以下操作:
public static String GetAssemblyNameContainingType(String typeName) { foreach (Assembly currentassembly in AppDomain.CurrentDomain.GetAssemblies()) { Type t = currentassembly.GetType(typeName, false, true); if (t != null) {return currentassembly.FullName;} } return "not found"; }
这也假定您的类型在根中声明。 您需要在名称中提供命名空间或封闭类型,或以相同的方式迭代。