的背景是如下如何創建二進制格式化一個SerializationBinder,處理的各類移動從一個集和命名空間到另一個
- 我想移動它以不同的項目 重構代碼
- 一些這個代碼的包括用於 發送和跨多個終端接收數據序列化的DTO的
- 如果我走動的代碼,系列化中斷(因此它是與舊版本我的應用程序的不 向後兼容)
解決這個問題是,讓我在某種意義上從一種類型到另一種「重定向」的SerializationBinder。
因此,我想創建一個SerializationBinder來滿足這種需求。但是它必須通過滿足下列要求
- 到SerializationBinder的投入應該是舊型 到新的類型映射列表,這樣做。映射應該包括老總成 名(無版,無公鑰標記)和 類型(名稱空間和名稱)的舊的完整名稱以及新的組件名稱和新 全稱類型的
- 對於輸入中的類型,應該忽略程序集的版本號
- 它應該處理泛型,如果我的類型碰巧是泛型 (List,Dictionary等),而不需要在泛型中包含輸入
- 對於任何不在輸入中的東西(例如,沒有移動的類型或移動的類型或者像數據集那樣的.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
}
}
我已經說過,要求是使用BinaryFormatter – Mark
實際上,你沒有(至少不清楚),並明確地詢問是否有什麼東西可以做到你想要的(最終結果是向後 - 兼容的序列化,不是嗎?),作爲開發人員和我,作爲有人試圖幫助在必要時不考慮替代品的人,這將是不負責任的。我都提供了替代解決方案,並給了你一些嘗試,使用BinaryFormatter。您是否爲BinaryFormatter指定了FormatterAssemblyStyle.Simple? – dodexahedron
我看不到如何改變中流串行化方法將允許向後兼容性? – Casey