SerializationBinder también fue mi solución. Pero tengo la clase en una DLL a la que se hace referencia. Entonces tengo que buscar en todos los ensamblajes de carga.He modificado las respuestas bevor con el parámetro si la carpeta debe buscar en dlls.
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace ibKastl.Helper
{
public static class BinaryFormatterHelper
{
public static T Read<T>(string filename, Assembly currentAssembly)
{
T retunValue;
FileStream fileStream = new FileStream(filename, FileMode.Open);
try
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Binder = new SearchAssembliesBinder(currentAssembly,true);
retunValue = (T)binaryFormatter.Deserialize(fileStream);
}
finally
{
fileStream.Close();
}
return retunValue;
}
public static void Write<T>(T obj, string filename)
{
FileStream fileStream = new FileStream(filename, FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(fileStream, obj);
}
finally
{
fileStream.Close();
}
}
}
sealed class SearchAssembliesBinder : SerializationBinder
{
private readonly bool _searchInDlls;
private readonly Assembly _currentAssembly;
public SearchAssembliesBinder(Assembly currentAssembly, bool searchInDlls)
{
_currentAssembly = currentAssembly;
_searchInDlls = searchInDlls;
}
public override Type BindToType(string assemblyName, string typeName)
{
List<AssemblyName> assemblyNames = new List<AssemblyName>();
assemblyNames.Add(_currentAssembly.GetName()); // EXE
if (_searchInDlls)
{
assemblyNames.AddRange(_currentAssembly.GetReferencedAssemblies()); // DLLs
}
foreach (AssemblyName an in assemblyNames)
{
var typeToDeserialize = GetTypeToDeserialize(typeName, an);
if (typeToDeserialize != null)
{
return typeToDeserialize; // found
}
}
return null; // not found
}
private static Type GetTypeToDeserialize(string typeName, AssemblyName an)
{
string fullTypeName = string.Format("{0}, {1}", typeName, an.FullName);
var typeToDeserialize = Type.GetType(fullTypeName);
return typeToDeserialize;
}
}
}
Uso:
const string FILENAME = @"MyObject.dat";
// Serialize
BinaryFormatterHelper.Write(myObject1,FILENAME);
// Deserialize
MyObject myObject2 = BinaryFormatterHelper.Read<MyObject>(FILENAME, Assembly.GetExecutingAssembly()); // Current Assembly where the dll is referenced
era el objeto serializado desde los conjuntos de pre-fusión o post-fusionar asambleas? –
Odio decirlo, pero otra razón más es que siempre trato de desalentar a las personas de usar BinaryFormatter. Este acoplamiento demasiado cerrado al tipo de metadatos causa grandes cantidades de dolor. Puedo recomendar mejores opciones si estás interesado en evitar esto (y muchos otros escenarios de dolor) en el futuro. –
¿Sabía que la serialización binaria no pretende ser un formato de almacenamiento, verdad? Solo debe ser un formato de transporte temporal, existen demasiados límites para el almacenamiento a largo plazo de objetos cuando se realiza a través del serializador binario. Actualiza tu programa y adiós a los archivos antiguos. –