Как создать SerializationBinder для двоичного форматера, который обрабатывает перемещение типов из одной сборки и пространства имен в другую

Контекст выглядит следующим образом

Я хочу реорганизовать код, переместив его в разные проектыЧасть этого кода состоит из сериализуемых DTO, которые используются для отправки и получения данных через несколько конечных точекЕсли я перемещаю код, сериализация нарушается (поэтому он не имеет обратной совместимости со старыми версиями моего приложения)

Решением этой проблемы является SerializationBinder, который позволяет мне «перенаправлять» в некотором смысле от одного типа к другому.

Поэтому я хочу создать SerializationBinder для удовлетворения этой потребности. Тем не менее, это должно быть сделано путем удовлетворения следующих требований

Входные данные для SerializationBinder должны быть списком сопоставлений старого типа и нового типа. Отображение должно включать старое имя сборки (без версии, без токена открытого ключа) и старое полное имя типа (пространство имен и имя), а также новое имя сборки и новое полное имя типаДля типов, которые находятся во входах, номера версий сборок следует игнорироватьОн должен обрабатывать дженерики, если мои типы оказываются в дженериках (список, словарь и т. Д.) Без необходимости включать дженерики во входные данныеДля всего, что отсутствует во входных данных (например, типы, которые не были перемещены, или типы .NET, такие как набор данных, например), по умолчанию следует использовать готовый алгоритм двоичного сериализатора.

Это возможно или я сплю? Есть ли что-то, что уже делает это? Я бы предположил, что это общая проблема.

До сих пор я не вижу простого способа сделать 3 и вообще никакого способа сделать 4.

Вот попытка

public class SmartDeserializationBinder : SerializationBinder
{
    /// <summary>
    /// Private class to handle storing type mappings
    /// </summary>
    private class TypeMapping
    {
        public string OldAssemblyName { get; set; }
        public string OldTypeName { get; set; }
        public string NewAssemblyName { get; set; }
        public string NewTypeName { get; set; }
    }

    List<TypeMapping> typeMappings;

    public SmartDeserializationBinder()
    {
        typeMappings = new List<TypeMapping>();
    }

    public void AddTypeMapping(string oldAssemblyName, string oldTypeName, string newAssemblyName, string newTypeName)
    {
        typeMappings.Add(new TypeMapping()
        {
            OldAssemblyName = oldAssemblyName,
            OldTypeName = oldTypeName,
            NewAssemblyName = newAssemblyName,
            NewTypeName = newTypeName
        });
    }

    public override Type BindToType(string assemblyName, string typeName)
    {
        //Need to handle the fact that assemblyName will come in with version while input type mapping may not
        //Need to handle the fact that generics come in as mscorlib assembly as opposed to the assembly where the type is defined.
        //Need to handle the fact that some types won't even be defined by mapping. In this case we should revert to normal Binding... how do you do that?

        string alternateAssembly = null;
        string alternateTypeName = null;
        bool needToMap = false;
        foreach (TypeMapping mapping in typeMappings)
        {
            if (typeName.Contains(mapping.OldTypeName))
            {
                alternateAssembly = mapping.NewAssemblyName;
                alternateTypeName = mapping.NewTypeName;
                needToMap = true;
                break;
            }
        }

        if (needToMap)
        {
            bool isList = false;
            if (typeName.Contains("List`1"))
                isList = true;
            // other generics need to go here

            if (isList)
                return Type.GetType(String.Format("System.Collections.Generic.List`1[[{0}, {1}]]", alternateTypeName, alternateAssembly));
            else
                return Type.GetType(String.Format("{0}, {1}", alternateTypeName, alternateAssembly));
        }
        else
            return null; // this seems to do the trick for binary serialization, but i'm not sure if it is supposed to work
    }
}

Ответы на вопрос(3)

Ваш ответ на вопрос