如何通过反射从引用的程序集中获取类型

时间:2010-02-18 18:26:23

标签: c# reflection

假设我有一个工厂方法,它想要构建一个在运行时通过反射选择的类型的实例。进一步假设我的工厂方法是通用代码,它不直接引用包含指定类型的程序集,尽管它将从具有必需程序集引用的应用程序中运行。

如何编写可以找到此类型的代码?如果我做以下

public object CreateInstance(string typeName)
{
    Type desiredType = Assembly.GetExecutingAssembly().GetType(typename);

    // Instantiate the type...
}

这似乎失败了,因为未在执行程序集中定义类型。如果我可以在运行时获得所有程序集,我可以迭代它们并找到哪一个包含我想要的类型。但我看不到这样做的方法。 AppDomain.CurrentDomain.GetAssemblies()看起来很有希望,但不会返回我在项目中引用的所有程序集。

编辑:有几个人指出我需要加载程序集。麻烦的是,这段代码不知道它应该加载哪个程序集,因为我试图以不依赖于其他程序集的方式编写这段代码。

我故意遗漏了typeName的细节,因为在我的实际代码中,从字符串到类型的映射实际上更复杂。实际上,类型由包含指定字符串的自定义属性标识,但是如果我可以获取类型列表,则将列表限制为所需类型没有问题。

3 个答案:

答案 0 :(得分:12)

您可以使用GetReferencedAssemblies并遍历所有类型,直到找到您要查找的类型。

var t = Assembly
   .GetExecutingAssembly()
   .GetReferencedAssemblies()
   .Select(x => Assembly.Load(x))
   .SelectMany(x => x.GetTypes()).First(x => x.FullName == typeName);

虽然它可能不是最高效的。然后,你 使用反射。

答案 1 :(得分:11)

AppDomain.CurrentDomain.GetAssemblies()的调用仅返回当前加载到AppDomain的DLL集。 DLL按需加载到CLR进程中;因此,在实际使用之前,它不会包含项目中引用的所有DLL。

您可以做的是使用typeof表达式强制程序集进入流程。例如

var force1 = typeof(SomeTypeInTheProject).Assembly;
var force2 = typeof(SomeTypeInProject2).Assembly;

答案 2 :(得分:3)

AppDomain.CurrentDomain.GetAssemblies()仅返回已加载的程序集。因此,如果尚未加载已引用的程序集,则需要加载它。