Here's the code. It only addresses how to deserialize a stream that was
originally serialized using a different assembly version. It doesn't
address handling differences in the objects interface that may have
occurred between versions, but the code that Chris posted does.

using System;
using System.Reflection;

// Run the application once, then
// change the version number, recompile
// and rerun. Without the attaching the
// custom binder to the formatter, deserialization
// will throw an exception.
[assembly: AssemblyVersion("1.0.0.0")]
// give the assembly a strong name
[assembly: AssemblyKeyFile("key.snk")]

namespace VersionedLibrary
{
 [Serializable]
 // The object to be serialized.
 public class TestClass
 {
  private string _name;

  public TestClass( string name )
  {
   _name = name;
  }

  public string Name
  {
   get
   {
    return _name;
   }
   set
   {
    _name = value;
   }
  }
 }
}

---- new file ------

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using VersionedLibrary;

namespace TestSerializationVersions
{
 public class TestClassBinder : SerializationBinder
 {
  public TestClassBinder() : base()
  {
  }

  public override Type BindToType(
   string assemblyName,
   string typeName
   )
  {
   // regardless of the assembly version
   // encoded in the serialized stream,
   // return the type that's in the current
   // assembly - i.e. the most recent version.
   return typeof(TestClass);
  }
 }

 class App
 {
  private const string filename = "object.bin";

  static void Main(string[] args)
  {

   FileStream stream = null;
   IFormatter formatter = new BinaryFormatter();
   // attach the custom binder to this formatter.
   formatter.Binder = new TestClassBinder();

   TestClass c = null;

   try
   {
    // The first time through,
    // serialize the object and
    // save it to a file.
    if( !File.Exists( filename ) )
    {
     stream = File.Create( filename );
     c = new TestClass( "Test" );
     formatter.Serialize( stream, c );
    }
    // The file already exists, so try to
    // deserialize it.
    else
    {
     stream = File.OpenRead( filename );
     c = (TestClass)
formatter.Deserialize( stream );
    }
   }
   finally
   {
    if( stream != null )
    {
     stream.Close();
    }
   }

  }
 }
}



On Mon, 8 Jul 2002 11:31:06 -0700, Chris Sells <[EMAIL PROTECTED]>
wrote:

>I'd like to see that, Paul, if you wouldn't mind sharing.
>
>Chris Sells
>http://www.sellsbrothers.com/
>
>> -----Original Message-----
>> From: Moderated discussion of advanced .NET topics. [mailto:ADVANCED-
>> [EMAIL PROTECTED]] On Behalf Of Paul Currit
>> Sent: Monday, July 08, 2002 11:15 AM
>> To: [EMAIL PROTECTED]
>> Subject: Re: [ADVANCED-DOTNET] Serialization and assembly version
>redirection
>>
>> Thanks for everybody's help. I apologize, because the answer was there
>all
>> along but I didn't look hard enough initially. I found that
>subclassing
>> SerializationBinder and overriding the BindToType method and then
>setting
>> the IFormatter.Binder property to an instance of my custom
>> SerializationBinder class did just what I wanted.
>
>You can read messages from the Advanced DOTNET archive, unsubscribe from
Advanced DOTNET, or
>subscribe to other DevelopMentor lists at http://discuss.develop.com.

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to