动态对象的反序列化问题,说找不到程序集

inte_sleeper 2008-11-08 09:13:08
是这样的,我有这样一个类:
class MyClass{
string assemblyName;
object obj;
}
其中assemblyName是一个编译后类的DLL的名称,obj是根据这个DLL生成的对象。
我的程序是在运行时确定这个assemblyName,然后生成这个对象,并给对象里的属性赋值的。然后将这个对象用二进制序列化存到数据库中。
序列化的代码如下:
public static byte[] serialize(object obj) {
BinaryFormatter binFormatter = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
byte[] buffer = new byte[0];
binFormatter.Serialize(memStream, obj);
buffer = memStream.ToArray();
return buffer;
}

对对象进行反序列化的代码如下:
public static object deserialize(byte[] buffer) {
object obj = null;
MemoryStream memStream = new MemoryStream(buffer);
BinaryFormatter binFormatter = new BinaryFormatter();

obj = binFormatter.Deserialize(memStream);
return obj;
}

我看过,序列化是没有问题的。可是在反序列的时候,就会出现问题。
因为序列化的时候,是存储了对象的程序集信息的,可是在执行反序列化的这一句时:
obj = binFormatter.Deserialize(memStream);
它就报类似这样的错:
Unable to find assembly ”MyAssemblyNameInDLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null“,其中MyAssemblyNameInDLL是随便起的,就是DLL中的程序集名称。这是为什么呢?
我的理解是,它既然在序列化时存储了程序集的相关信息,那在反序列化时就要去读取对应的程序集,可能是从一个特定的位置读取,可是我试过system目录和.net framework的DLL的目录,都不行。有什么解决方法吗?我觉得最好,是能够自己指定程序集的位置,不要从一个特定的位置去读,否则这样太不灵活了。
垦请大家指教,谢谢了。
...全文
358 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wzw200 2008-11-10
  • 打赏
  • 举报
回复
要右建 添加引用你的DLL
inte_sleeper 2008-11-10
  • 打赏
  • 举报
回复
问题解决了,我把DLL移至BIN文件夹下就可以了.
inte_sleeper 2008-11-10
  • 打赏
  • 举报
回复
To KimmKing:
我用AppDomain.CurrentDomain.Load()加载了这DLL,在AppDomain.CurrentDomain.GetAssemblies()中也看到有这个Assembly了,可是为什么反序列化时还是不行?同样的错误...我是在反序列化那句执行之前加载这个DLL的.

public static object deserialize(byte[] buffer,string assembly) {
object obj = null;
MemoryStream memStream = new MemoryStream(buffer);
BinaryFormatter binFormatter = new BinaryFormatter();

FileStream fs = new FileStream(assembly, FileMode.Open,FileAccess.Read);
byte[] rawAssembly = new byte[fs.Length];
using (BinaryReader reader = new BinaryReader(fs)) {
reader.Read(rawAssembly, 0, (int)fs.Length);
}
AppDomain.CurrentDomain.Load(rawAssembly);

obj = binFormatter.Deserialize(memStream);
return obj;
}
acqy 2008-11-10
  • 打赏
  • 举报
回复
昨天有事,一天没上CSDN。闻楼主喜讯,恭喜恭喜!哈哈
inte_sleeper 2008-11-10
  • 打赏
  • 举报
回复
...动态创建的DLL,显然不可能静态添加引用....
inte_sleeper 2008-11-08
  • 打赏
  • 举报
回复
To acqy:
assemblyName是Path的全名的。
MyClass其实是在编译时已经存在于当前AppDomain中的,并且不会改变。改变的是MyClass中的assemblyName以及根据这个DLL生成的obj.

To KimmKing:
恩,非常感谢,我试一下~~~
tinalucky 2008-11-08
  • 打赏
  • 举报
回复
动态加载:

Assembly myAssembly = Assembly.LoadFrom("your dll file");
Type type = myAssembly.GetType("your class in dll file");

object obj = Activator.CreateInstance(type);//create instrance

MethodInfo method = type.GetMethod("method which you want to use");
kimmking 2008-11-08
  • 打赏
  • 举报
回复
那是因为当前的AppDomain 找不到要用的程序集、类型。

1、前期绑定,直接将dll添加到项目的引用中。

2、后期动态加载:
确定AppDomain 中的所有可用程序集中包括要使用的类型。
(使用AppDomain.GetAssemblies()得到所有程序集,看看,Assembly.GetTypes()可以得到所有类型)

如果没有需要的Assembly,可以运行时通过Assembly.Load LoadFile LoadFrom等几个static的方法加载到当前AppDomain
然后方可使用。
acqy 2008-11-08
  • 打赏
  • 举报
回复
也就是MyClass中的assemblyName指定了序列化、反序列化的assembly,然后在load assembly后,将assembly的实体放在MyClass的obj中么?

你先要确保两点:
1、assemblyName要用Path的全名
2、序列化、反序列化的MyClass必须是单独定义在一个程序集中的同一个对象,否则类名相同,签名可能完全不同
inte_sleeper 2008-11-08
  • 打赏
  • 举报
回复
不是的,serialize和deserialize都是另外单独定义的。MyClass中的assemblyName只是引用了这个DLL的名称,以加载这个DLL。
acqy 2008-11-08
  • 打赏
  • 举报
回复
你的serialize、deserialize和MyClass都是定义在MyAssemblyNameInDll中么?

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧