Jak utworzyć narzędzie SerializationBinder dla formatu binarnego, które obsługuje przenoszenie typów z jednego zespołu i przestrzeni nazw do innego

Kontekst jest następujący

Chcę zmienić kod, przenosząc go do różnych projektówCzęść tego kodu składa się z serializowalnych DTO, które są używane do wysyłania i odbierania danych w wielu punktach końcowychJeśli przeniosę kod dookoła, łamanie serializacji (dlatego nie jest kompatybilne wstecz ze starszymi wersjami mojej aplikacji)

Rozwiązaniem tego problemu jest SerializationBinder, który pozwala mi na „przekierowanie” w pewnym sensie z jednego typu na inny.

Dlatego chcę stworzyć narzędzie SerializationBinder, aby zaspokoić tę potrzebę. Jednak musi to zrobić, spełniając następujące wymagania

Dane wejściowe do SerializationBinder powinny być listą starego typu do nowych mapowań typu. Mapowanie powinno zawierać starą nazwę zespołu (brak wersji, brak tokena klucza publicznego) oraz starą pełną nazwę typu (przestrzeń nazw i nazwa), a także nową nazwę zespołu i nową pełną nazwę typuW przypadku typów znajdujących się na wejściach numery wersji zespołów powinny być ignorowanePowinien obsługiwać generics, jeśli moje typy znajdują się w typach generycznych (List, Dictionary itp.) Bez konieczności dołączania generics do danych wejściowychW przypadku czegokolwiek, co nie znajduje się w danych wejściowych (tj. Typów, które nie zostały przeniesione lub typów .NET, takich jak na przykład zestaw danych), powinno domyślnie korzystać z algorytmu binarnego serializatora poza polem

Czy to możliwe, czy też śnię? Czy jest coś, co już to robi? Zakładam, że jest to powszechny problem.

Do tej pory nie widzę łatwego sposobu wykonania 3 i żadnego sposobu na zrobienie 4.

Oto próba

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
    }
}

questionAnswers(3)

yourAnswerToTheQuestion