C#;在转换为来自另一个程序集的SAME类时

时间:2010-06-13 14:28:37

标签: c# reflection casting

为了完全分离/解耦,我在一个装配中实现了一个DAL,它只是通过post-build事件复制到网站BIN文件夹。然后,应用程序开始的网站通过System.Reflection.Assembly.LoadFile加载该程序集。再次,使用反射,我从该程序集中的类构造了几个实例。然后,我在会话中存储对这些实例的引用(HttpContext.Current.Items)

稍后,当我尝试将对象存储在会话中时,我无法将它们转换为自己的类型(最初尝试接口,但是为了调试尝试转换为他们自己的类型),得到此错误:

 [A]DAL_QSYSCamper.NHibernateSessionBuilder cannot be cast to [B]
DAL_QSYSCamper.NHibernateSessionBuilder. Type A originates from 'DAL_QSYSCamper, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at 
location 'C:\Users\myusername\AppData\Local\Temp\Temporary ASP.NET 
Files\root\ad6e8bff\70fa2384\assembly\dl3\aaf7a5b0\84f01b09_b10acb01\DAL_QSYSCamper.DLL'. 
Type B originates from 'DAL_QSYSCamper, Version=1.0.0.0, Culture=neutral, 
PublicKeyToken=null' in the context 'LoadNeither' at 
location 'C:\Users\myusername\Documents\Projects\QSYS\Deleteme\UI\MVCClient\bin\DAL_QSYSCa
mper.DLL'.

这种情况正在发生,而VS-VS中的调试设法停止进入源DAL项目,即使我已从程序集加载并且项目未被网站项目引用(它们都在解决方案中)。

我确实理解错误,但我不明白如何以及为什么从两个位置使用/加载程序集 - 我只从文件中加载一次,并且没有参考项目。

应该提到我也使用Windsor进行DI。尝试从会话中提取对象的对象是A)来自该DAL程序集的类; B)由Windsor注入网站课程。 我将努力为这个问题添加一些示例代码,但是想把它放在外面以防我明白我做错了。

2 个答案:

答案 0 :(得分:7)

原因在Assembly.LoadFile()方法的备注部分中给出:

  

使用LoadFile方法加载和检查具有相同标识但位于不同路径的程序集。 LoadFile不会将文件加载到LoadFrom上下文中,也不会像LoadFrom方法那样使用加载路径解析依赖关系。在这种有限的情况下,LoadFile非常有用,因为LoadFrom不能用于加载具有相同标识但路径不同的程序集;它只会加载第一个这样的组件。

也许有点密集。汇编加载上下文是一篇棘手的主题,由Suzanne Cook撰写。最终的效果是,当您在其他地方使用该程序集的类型时,您将再次加载程序集 ,这些类型将与LoadFile程序集中的类型不匹配,因为程序集具有不同的标识

如上所述,使用Load或LoadFrom来避免此问题。

答案 1 :(得分:1)

除非我通过定义误解了你的问题,否则从不同的程序集中转换到同一个类不会转换到同一个类。 Assembly1.Class<> Assembly2.Class,即使元素/方法/接口和属性是相同的。

这种“演员”成功的唯一方法(据我所知)是通过序列化。在引用任何要转换的程序集时,在项目中确保它被引用到同一位置,并删除任何重复的目标代码并将其托管在一个位置。