FsPickler
FsPickler copied to clipboard
Migration to another serialization library
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.