2

プラグインシステムを作成しました。プログラムを再起動しても機能し続けることができるように、プロパティを保存/ロードしたいと思います。バイナリシリアル化を使用しています。問題は、それらをシリアル化することはできますが、逆シリアル化することはできないということです。デシリアライズ中に「アセンブリが見つかりません」という例外がスローされます。シリアル化されたデータを復元するにはどうすればよいですか?

4

3 に答える 3

4

ここで私は何かを見つけました。:)

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;

            }

手伝ってくれてありがとう :)

于 2010-05-25T07:27:41.917 に答える
2

fuslogvw.exeツールを使用して、CLRがアセンブリを検索している場所を見つけます。

于 2010-05-24T15:23:14.923 に答える
1

多くの場合、データを逆シリアル化するときにプラグインアセンブリがロードされません。これは外部のプラグインアセンブリであるため、明示的にロードしていると思います。アセンブリをロードする前に、プロパティオブジェクトを逆シリアル化する可​​能性があります。現在のAppDomainでAssemblyResolveイベントとAssemblyLoadイベントをフックし、それらがいつ呼び出されるかを正確に監視することで、問題を診断して修正できます。

AssemblyResolveを使用して、明示的なアセンブリロードコードを自分で挿入し、ロードされたアセンブリを返すことで、ロードエラーを修正することもできます。ちょっと後ろ向きなのでお勧めしません。

AssemblyResolve

于 2010-05-24T15:25:17.713 に答える