Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration to another serialization library #130

Open
ingted opened this issue Nov 7, 2024 · 0 comments
Open

Migration to another serialization library #130

ingted opened this issue Nov 7, 2024 · 0 comments

Comments

@ingted
Copy link

ingted commented Nov 7, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant