在开发中,经常会遇到这种情况,在A.dll中需要反射B.dll中的类型,如果稍不注意,就会产生运行时错误。关于跨程序集的反射,记住两点就可以:
(1)如果使用typeof,编译能通过,则跨程序集的反射一定可以正常运行。可以说,typeof是支持强类型的。比如
(2)如果使用Type.GetType,情况就复杂些,这是因为Type.GetType是非强类型的。Type.GetType的参数是一个string,当string表示的目标类型不在当前程序集中,则运行时Type.GetType会返回null。解决的办法是:首先加载目标程序集,然后再使用Assembly.GetType方法。如
(1)如果使用typeof,编译能通过,则跨程序集的反射一定可以正常运行。可以说,typeof是支持强类型的。比如
Type supType = typeof(EnterpriseServerBase.DataAccess.IDBAccesser) ;
如果当前程序集没有添加对EnterpriseServerBase.dll的引用,则编译会报错。(2)如果使用Type.GetType,情况就复杂些,这是因为Type.GetType是非强类型的。Type.GetType的参数是一个string,当string表示的目标类型不在当前程序集中,则运行时Type.GetType会返回null。解决的办法是:首先加载目标程序集,然后再使用Assembly.GetType方法。如
Assembly asmb = Assembly.LoadFrom("EnterpriseServerBase.dll") ;
Type supType = asmb.GetType("EnterpriseServerBase.DataAccess.IDBAccesser") ;
注意,当使用Type.GetType的时候,即使你添加了对EnterpriseServerBase.dll的引用,Type.GetType("EnterpriseServerBase.DataAccess.IDBAccesser")也会返回null,这是因为Type.GetType只会在当前程序集中进行类型搜索!
Type supType = asmb.GetType("EnterpriseServerBase.DataAccess.IDBAccesser") ;
Feedback
这几天也刚好在看反射的内容,jeffrey前辈的那本书上也有讲到跨程序集的反射调用,呵呵~~加深印象了
如果编译期加了“引用”就是静态引用,是应用域一级的依赖,就不存在“跨Assembly”引用的问题。
使用Type.GetType()是用来获取“跨Assembly”的唯一方式,目的是为了解决动态引用,但是必须使用完全限定名(AssemblyQualifiedName),这是.net framework提供的标准解决方案。如果只提供类型的FullName则指当前运行的Assembly,仍然是静态引用;如果提供类型的AssemblyQualifiedName则按照规定的顺序搜索Assembly,然后动态地加入应用域中,这个顺序是GAC、本地、私有路径、公有路径。需要特别指出的是,如果该Assembly是动态生成的,则稍稍复杂一点,可参考我的文章:http://www.cnblogs.com/Barton131420/articles/217905.html
使用完全限定名是避免循环引用、减少模块依赖的重要手段。Web.Config中的httpHandlers section和httpModules section采用的就是完全限定名。
使用Type.GetType()是用来获取“跨Assembly”的唯一方式,目的是为了解决动态引用,但是必须使用完全限定名(AssemblyQualifiedName),这是.net framework提供的标准解决方案。如果只提供类型的FullName则指当前运行的Assembly,仍然是静态引用;如果提供类型的AssemblyQualifiedName则按照规定的顺序搜索Assembly,然后动态地加入应用域中,这个顺序是GAC、本地、私有路径、公有路径。需要特别指出的是,如果该Assembly是动态生成的,则稍稍复杂一点,可参考我的文章:http://www.cnblogs.com/Barton131420/articles/217905.html
使用完全限定名是避免循环引用、减少模块依赖的重要手段。Web.Config中的httpHandlers section和httpModules section采用的就是完全限定名。