客户端为winform,服务端为remoting host in iis
客户端设计了一个插件功能,需要用反射动态加载程序集,该程序集中的一个类需要序列化到服务器端再执行某个方法。
由于该类为动态加载的类,服务端所引用的程序集中找不到此类,所以在反序列化时就会抛出“无法找到程序集”的异常。
请问针对这种情况有什么办法解决呢?

解决方案 »

  1.   

    1.将dll加入强名称,注册到全局程序集缓存中2.在反序列化使用的IFormatter 对象加入Binder 属性,使其获取要反序列化的对象所在的程序集,示例如下:
     public void DeSerialize( byte [] data, int offset) 

         IFormatter formatter = new BinaryFormatter(); 
         formatter.Binder = new UBinder(); 
         MemoryStream stream = new MemoryStream(data, offset, stringlength); 
        this .m_bodyobject = ( object )formatter.Deserialize(stream); 

      
    public class UBinder:SerializationBinder 

        public override Type BindToType( string assemblyName, string typeName) 
         { 
            Assembly ass = Assembly.GetExecutingAssembly(); 
           return ass.GetType(typeName); 
         } 
      

  2.   

    1.加入强名称的方法肯定不行
    2.序列化不是用代码实现的,是给类加上了序列化特性,由.net自动完成的序列化及反序列化,所以这个方法也不可取
      

  3.   

    google了一气找到了点资料说是使用AppDomain.CurrentDomain.AssemblyResolve事件处理,但是经我测试并不执行此事件,可能是自己没弄明白,不知道有没有人用过这个事件呢。
    另外当我把反射加载的程序集放到bin文件夹下的时候即使没有引用的程序集也可以反序列化成功(以前客户端的程度集有一部份没放到bin文件夹下为了更新程序集保持路径一致服务器端也放到bin文件夹外)
      

  4.   

    同一个dll,引用和动态加载所产生的程序集是不一样的
      

  5.   

    楼主,不会的
    ——任何对象在反序列化时,就已经 将 对象类型保存了起来;你之所以无法反序列化,值是因为你的代码执行到 反序列化时,你所需要的程序集没有被加载而已!!我会在每一个 Program  中加上这样几行代码:Assembly.Load(插件1的命名空间);
    Assembly.Load(插件2的命名空间);
    Assembly.Load(插件3的命名空间);
    ——在最开始的时候,就将 需要的插件 加载到程序域中!!!而不是,之后需要时,就加载插件程序集;
      

  6.   

    插件式的程序,我写过几个:http://hi.baidu.com/my_responsibility/album/c%23%20sqlforever%20%A1%AA%A1%AA2011%CD%F5%C5%C6%CF%EE%C4%BF%D6%AE%D2%BBhttp://hi.baidu.com/my_responsibility/album/c%23%20webcreate%202.5%20%A1%AA%A1%AA2011%CD%F5%C5%C6%CF%EE%C4%BF——这两个项目 ,右键菜单,导航栏,工具栏,子窗体 都是用插件的形式扩展出来的;
    都是序列化保存和反序列化加载——没有任何问题!!!到目前为止,我还没有遇到 反序列化的问题!!!
      

  7.   

    服务端是IIS下的虚拟目录,如果把程序集放到虚拟目录下,就会出现找不到程序集的问题,如果放到虚拟目录/bin下就不会出问题(程序集肯定不少的)