プラグインシステムを作成しました。プログラムを再起動しても機能し続けることができるように、プロパティを保存/ロードしたいと思います。バイナリシリアル化を使用しています。問題は、それらをシリアル化することはできますが、逆シリアル化することはできないということです。デシリアライズ中に「アセンブリが見つかりません」という例外がスローされます。シリアル化されたデータを復元するにはどうすればよいですか?
3 に答える
ここで私は何かを見つけました。:)
http://techdigger.wordpress.com/2007/12/22/deserializing-data-into-a-dynamically-loaded-assembly/
私はこのアプローチを使用しましたが、問題なく動作しました。
Firs はバインダー クラスを次のように定義しました。
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;
}
手伝ってくれてありがとう :)
fuslogvw.exeツールを使用して、CLRがアセンブリを検索している場所を見つけます。
多くの場合、データを逆シリアル化するときにプラグインアセンブリがロードされません。これは外部のプラグインアセンブリであるため、明示的にロードしていると思います。アセンブリをロードする前に、プロパティオブジェクトを逆シリアル化する可能性があります。現在のAppDomainでAssemblyResolveイベントとAssemblyLoadイベントをフックし、それらがいつ呼び出されるかを正確に監視することで、問題を診断して修正できます。
AssemblyResolveを使用して、明示的なアセンブリロードコードを自分で挿入し、ロードされたアセンブリを返すことで、ロードエラーを修正することもできます。ちょっと後ろ向きなのでお勧めしません。