我写了一个插件系统,我想保存/加载它们的属性,这样如果程序重新启动,它们就可以继续工作。我使用二进制序列化。问题是它们可以序列化但不能反序列化。在反序列化期间抛出“无法找到程序集”异常。如何恢复序列化数据?
问问题
3463 次
3 回答
4
好的,我在这里找到了一些东西。:)
http://techdigger.wordpress.com/2007/12/22/deserializing-data-into-a-dynamically-loaded-assembly/
我使用了这种方法,它没有任何问题。
Firs 定义了一个 binder 类:
internal sealed class VersionConfigToNamespaceAssemblyObjectBinder : SerializationBinder {
public override Type BindToType(string assemblyName, string typeName) {
Type typeToDeserialize = null;
try{
string ToAssemblyName = assemblyName.Split(',')[0];
Assembly[] Assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly ass in Assemblies){
if (ass.FullName.Split(',')[0] == ToAssemblyName){
typeToDeserialize = ass.GetType(typeName);
break;
}
}
}
catch (System.Exception exception){
throw exception;
}
return typeToDeserialize;
}
}
然后是序列化方法:
public static byte[] Serialize(Object o){
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.AssemblyFormat
= System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
formatter.Serialize(stream, o);
return stream.ToArray();
}
public static Object BinaryDeSerialize(byte[] bytes){
MemoryStream stream = new MemoryStream(bytes);
BinaryFormatter formatter = new BinaryFormatter();
formatter.AssemblyFormat
= System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
formatter.Binder
= new VersionConfigToNamespaceAssemblyObjectBinder();
Object obj = (Object)formatter.Deserialize(stream);
return obj;
}
我在需要的地方使用它们。
protected void SaveAsBinary(object objGraph, string fileName)
{
byte[] serializedData = Serialize(objGraph);
File.WriteAllBytes(fileName, serializedData);
}
protected object LoadFomBinary(string fileName)
{
object objGraph = null;
try
{
objGraph = BinaryDeserialize(File.ReadAllBytes(fileName));
}
catch (FileNotFoundException fne)
{
#if DEBUG
throw fne;
#endif
}
return objGraph;
}
感谢帮助 :)
于 2010-05-25T07:27:41.917 回答
2
使用 fuslogvw.exe 工具找出 CLR 在哪里搜索程序集。
于 2010-05-24T15:23:14.923 回答
1
很可能,您的插件程序集在您反序列化数据时未加载。因为它是一个外部插件程序集,我猜你正在显式加载它。您可能在加载程序集之前反序列化属性对象。您可以通过在当前 AppDomain 上挂钩 AssemblyResolve 和 AssemblyLoad 事件并准确观察它们何时被调用来诊断和解决问题。
您还可以使用 AssemblyResolve 通过自己将显式的程序集加载代码放入其中并返回加载的程序集来修复加载错误。我不推荐这个,因为它有点倒退。
于 2010-05-24T15:25:17.713 回答