C# 如何从从另一个文件夹中加载的程序集中获取类型?

C# 如何从从另一个文件夹中加载的程序集中获取类型?,c#,.net,reflection,C#,.net,Reflection,我使用以下代码: Assembly.LoadFile("the assembly in another folder"); var type = Type.GetType("the full name of the type"); 即使程序集已在此代码行之前加载,它在类型中始终返回null PS:我确实传入了程序集限定名称,包括命名空间、类型名称、程序集名称、版本和公共令牌。type。GetType仅搜索调用程序集中的类型和mscorlib.dll中的类型,除非传递类型的程序集限定名称 编辑

我使用以下代码:

Assembly.LoadFile("the assembly in another folder");
var type = Type.GetType("the full name of the type");
即使程序集已在此代码行之前加载,它在
类型中始终返回null


PS:我确实传入了程序集限定名称,包括命名空间、类型名称、程序集名称、版本和公共令牌。

type。GetType
仅搜索调用程序集中的类型和mscorlib.dll中的类型,除非传递类型的程序集限定名称

编辑

似乎
Type.GetType
只能从加载上下文中的程序集检索
Type
实例。使用
LoadFile
加载的程序集位于中,使用
LoadFrom
加载的程序集位于加载自上下文中;这两种上下文都不允许您使用
Type.GetType
,因此解析将失败。显示当程序集所在的目录被添加为探测私有路径时,可以为程序集检索
类型
信息,因为它将在加载上下文中结束,但在其他上下文中失败。

您可以尝试此

Assembly.GetAssembly假定您有该类型的实例,type.GetType假定您有包含程序集名称的完全限定类型名称

您可以指定程序集所在的路径

如果只有基类型名称,则需要执行以下操作:

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";
}
Assembly assem = Assembly.LoadFile("assemblyLocation");
assem.GetType("typeName");

这还假定您的类型是在根目录中声明的。您需要在名称中提供名称空间或封闭类型,或者以相同的方式进行迭代。

最简单的方法是将Assembly.LoadFile的返回值捕获到变量中,并对其调用GetType,如下所示:

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";
}
Assembly assem = Assembly.LoadFile("assemblyLocation");
assem.GetType("typeName");
您可能想考虑对这个程序集进行引用,如果您想从中提取类型,或者按照其他人的建议做一个更通用的方法来循环所有加载的程序集。< /P> < P>“当您必须使用<代码>类型”时,“适当的”(MS推荐)方法。
对于程序集中不在加载上下文中但在加载自上下文或无上下文上下文上下文中的类型,将绑定到事件。以下代码相对有效:

// 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上
使用这种方法有一些严重的缺点

LoadFile不会像LoadFrom方法那样将文件加载到LoadFrom上下文中,也不会使用加载路径解析依赖项


因此,如果可能,不要使用LoadFile。生成的程序集在无上下文上下文中加载,这比从上下文加载有更多的缺点。相反,将从加载路径自动加载use和dependencies。

这是否与汇编语言有某种关联?@KirilKirov:No。它是.Net中的一种类型。@Austin-ah,谢谢:)我被标签误导了。加载程序集时要小心,因为一旦你将它们加载到AppDomain中,你就不能再卸载它们了。如果您有很多程序集要加载,请考虑创建单独的AppDomain,它将完成处理程序集和返回结果的工作,然后再发布。我不建议这样做。而是绑定到事件。这样,您只返回所需的程序集,在上面的代码中,您搜索每个加载的程序集,然后开始加载当前不需要的程序集。我确实传入了程序集限定名,包括名称空间、类型名称、程序集名称和版本、公共令牌。@翠鹏飞只是为了消除明显的,您确定程序集限定名与静态引用程序集并调用
typeof(TypeName).AssemblyQualifiedName
)时得到的区分大小写的值完全匹配吗?@CuiPengFei:我尝试使用
Type.GetType
,但没有成功,因此我支持@EvanWilliams ans作为最佳解决方案。