Skip to content

Migration to another serialization library #130

@ingted

Description

@ingted

Hi!

For those one who wants to migrate to another lib and you found that old serialized data not working now, here is a workaround:

Modify loadMemberInfo to force to assign a type name mapped to make assembly.GetType silent.

assembly.GetType(TypeMap.GetAlternativeName(assembly.FullName, tIP.Name), throwOnError = true) |> 

type TypeMap () =

    // 靜態 ConcurrentDictionary 映射 Assembly 和名稱對應的替代名稱
    static let typeMap = ConcurrentDictionary<string, ConcurrentDictionary<string, string>>()

    /// 新增或更新 Assembly 和 Name 對應的替代名稱
    static member AddOrUpdateAlternativeName(assembly: string, name: string, altName: string) =
        let nameMap = typeMap.GetOrAdd(assembly, fun _ -> ConcurrentDictionary<string, string>())
        nameMap.AddOrUpdate(name, altName, fun _ _ -> altName) |> ignore

    /// 根據 Assembly 和 Name 取得替代名稱,如果不存在則回傳原始名稱
    static member GetAlternativeName(assembly: string, name: string) =
        match typeMap.TryGetValue(assembly) with
        | true, nameMap ->
            match nameMap.TryGetValue(name) with
            | true, altName -> altName
            | false, _ -> name
        | false, _ -> name


let loadMemberInfo (tyConv : ITypeNameConverter option) 
                    (getAssembly : bool -> AssemblyInfo -> Assembly) 
                    (getMethodSignature : MethodInfo -> string) 
                    (enableAssemblyLoading : bool) (mI : CompositeMemberInfo) =

    let inline getFlags isStatic =
        let allVisibility = BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.FlattenHierarchy
        allVisibility ||| (if isStatic then BindingFlags.Static else BindingFlags.Instance)

    match mI with
    | NamedType(name, aI) ->
        printfn "NamedType: Name = %A, AssemblyInfo = %A" name aI
        let tI = { Name = name ; AssemblyInfo = aI }
        let tIP =
            match tyConv with
            | None -> tI
            | Some tc -> tc.ToDeserializedType tI

        let assembly = getAssembly enableAssemblyLoading tIP.AssemblyInfo
        assembly.GetType(TypeMap.GetAlternativeName(assembly.FullName, tIP.Name), throwOnError = true) |> fastUnbox<MemberInfo>

Of course you need to use dotPeek (etc...) to check the type mapping between new and old libraries and do stuffs like

TypeMap.AddOrUpdateAlternativeName(ass2.FullName, "FAkka.TA.TAType+-ctor@200-11", "FAkka.TA.TAType+-ctor@200-11")
TypeMap.AddOrUpdateAlternativeName(ass2.FullName, "FAkka.TA.TAType+-ctor@208-12", "FAkka.TA.TAType+-ctor@210-12")
TypeMap.AddOrUpdateAlternativeName(ass2.FullName, "FAkka.TA.TAType+-ctor@216-13", "FAkka.TA.TAType+-ctor@220-13")
TypeMap.AddOrUpdateAlternativeName(ass2.FullName, "FAkka.TA.TAType+-ctor@224-14", "FAkka.TA.TAType+-ctor@230-14")
TypeMap.AddOrUpdateAlternativeName(ass2.FullName, "FAkka.TA.TAType+-ctor@232-15", "FAkka.TA.TAType+-ctor@240-15")
TypeMap.AddOrUpdateAlternativeName(ass2.FullName, "FAkka.TA.TAType+-ctor@240-16", "FAkka.TA.TAType+-ctor@248-16")
TypeMap.AddOrUpdateAlternativeName(ass2.FullName, "FAkka.TA.TAType+-ctor@640-17<SLKey, SLTAKey, KeyOfSL>", "FAkka.TA.TAType+-ctor@648-17<SLKey, SLTAKey, KeyOfSL>")

Before FsPickler start to work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions