Assembly.GetReferencedAssemblies无法检测部分引用项目程序集的原因
问题原因
出现这个现象是.NET编译和运行时的默认机制导致的,和你有没有在项目里加引用没有直接关系:
- 首先是编译器的未使用引用裁剪逻辑:如果你当前项目里没有任何代码直接使用
SocialMedia.Infrastructure公开的任何类型、方法、属性等成员(比如仅添加了项目引用,但从未写过对应using语句、从未实例化该程序集内的类、从未调用过该程序集内的方法),编译器在生成输出程序集时,会直接把这个未实际使用的引用从程序集元数据的引用列表里移除,调用GetReferencedAssemblies()自然读不到。 - 其次是运行时的按需加载特性:就算你代码里写了对
SocialMedia.Infrastructure的使用,如果执行Assembly.GetExecutingAssembly().GetReferencedAssemblies()这行代码的节点,还没有触发过任何对SocialMedia.Infrastructure内类型的访问,该程序集就还没被加载到当前应用程序域中,此时查询也不会返回它。 - 你能正常检测到
SocialMedia.Core的原因很简单:要么是你当前项目本身直接使用了SocialMedia.Core里的类型,要么是你用到的其他依赖项的成员签名暴露了SocialMedia.Core的类型,编译器会保留对它的引用,运行时也会提前完成加载,所以可以被检测到。
验证和处理方案
- 验证裁剪逻辑:在当前项目任意位置加一行直接使用
SocialMedia.Infrastructure内公开类型的代码,比如var _ = typeof(/* 替换为SocialMedia.Infrastructure里的任意公开类名 */);,重新编译运行后就能在返回列表里看到该程序集。 - 强制加载目标程序集:如果不需要直接写调用代码但希望程序集被识别,可以在程序启动阶段手动执行
Assembly.Load("SocialMedia.Infrastructure")强制加载对应程序集,后续查询就能正常获取到。 - 注意区分两类引用:你在csproj文件里添加的项目引用,和编译后程序集元数据里存储的引用列表不是一一对应的,只有实际被代码使用到的引用才会被编译器保留。
问题场景参考截图:
内容的提问来源于stack exchange,提问作者Waad Sulaiman
相关产品推荐
相关产品推荐

