我想序列化包含純數據的模型對象(來自WPF MVVM)。這聽起來很簡單,但我不想使用.NET Framework中提供的Serialization屬性和東西。我只是想用我自己的方式序列化它。
所以這裏是我的一個類的簡化版本。使用SOLID原則序列化自定義對象
public class EntryKeyValuePair
{
public EntryKeyValuePair(string key, string value, bool isMultiline = false, bool isMandatory = true, bool isProtected = false)
{
Key = key;
Value = value;
IsMultiline = isMultiline;
IsMandatory = isMandatory;
IsProtected = isProtected;
}
public string Key { get; set; }
public string Value { get; set; }
public bool IsMultiline { get; set; }
public bool IsMandatory { get; set; }
public bool IsProtected { get; set; }
public static EntryKeyValuePair FromXML(XElement element, ICipher cipher)
{
string key = cipher.Decrypt(element.Element(nameof(Key)).Value);
string value = cipher.Decrypt(element.Element(nameof(Value)).Value);
bool isMultiline = bool.Parse(element.Element(nameof(IsMultiline)).Value);
bool isMandatory = bool.Parse(element.Element(nameof(IsMandatory)).Value);
bool isProtected = bool.Parse(element.Element(nameof(IsProtected)).Value);
return new EntryKeyValuePair(key, value, isMultiline, isMandatory, isProtected);
}
public XElement ToXML(ICipher cipher)
{
return new XElement(nameof(EntryKeyValuePair),
new XElement(nameof(Key),cipher.Encrypt(Key)),
new XElement(nameof(Value), cipher.Encrypt(Value)),
new XElement(nameof(IsMultiline), IsMultiline), new XElement(nameof(IsMandatory), IsMandatory),
new XElement(nameof(IsProtected), IsProtected));
}
}
這工作得很好。但這違反了單一責任原則,也可能違反其他原則。這也難以保持和擴展。
所以我想找到另一種方式。這裏是:
首先我定義了一個IStringFormatter
接口,它可以將數據格式化爲任何字符串數據格式,如XML和JSON。 (不知道壽)
interface IStringFormatter
{
string Name { get; set; }
Dictionary<string, string> FieldDictionary { get; }
string Format();
}
這裏的XMLStringFormatter的樣子:
class XmlStringFormatter : IStringFormatter
{
public XmlStringFormatter()
{
FieldDictionary = new Dictionary<string, string>();
}
public string Name { get; set; }
public Dictionary<string, string> FieldDictionary { get; }
public string Format()
{
var xElement = new XElement(Name, FieldDictionary.Keys.Select(key => new XElement(key, FieldDictionary[key])));
return xElement.ToString();
}
}
然後,我定義的ISerializer
序列化(或者說保存)我的數據對象的IStringFormatter
。
這裏是我如何實施這個 「序列化」 EntryKeyValurPair
:
internal class EntryKeyValurPairSerializer : ISerializer<EntryKeyValuePair>
{
public EntryKeyValuePair DeSerialize(IStringFormatter stringFormatter)
{
Dictionary<string, string> fieldDictionary = stringFormatter.FieldDictionary;
try {
string key = fieldDictionary[nameof(EntryKeyValuePair.Key)];
string value = fieldDictionary[nameof(EntryKeyValuePair.Value)];
bool isMandatory = bool.Parse(fieldDictionary[nameof(EntryKeyValuePair.IsMandatory)]);
bool isProtected = bool.Parse(fieldDictionary[nameof(EntryKeyValuePair.IsProtected)]);
bool isMultiline = bool.Parse(fieldDictionary[nameof(EntryKeyValuePair.IsMultiline)]);
return new EntryKeyValuePair(key, value, isMultiline, isMandatory, isProtected);
}
catch (KeyNotFoundException ex) {
throw new SerializationException(ex);
}
catch (FormatException ex) {
throw new SerializationException(ex);
}
}
public void Serialize(EntryKeyValuePair obj, IStringFormatter stringFormatter)
{
stringFormatter.Name = nameof(EntryKeyValuePair);
Dictionary<string, string> fieldDictionary = stringFormatter.FieldDictionary;
fieldDictionary.Add(nameof(EntryKeyValuePair.Key), obj.Key);
fieldDictionary.Add(nameof(EntryKeyValuePair.Value), obj.Value);
fieldDictionary.Add(nameof(EntryKeyValuePair.IsMandatory), obj.IsMandatory.ToString());
fieldDictionary.Add(nameof(EntryKeyValuePair.IsProtected), obj.IsProtected.ToString());
fieldDictionary.Add(nameof(EntryKeyValuePair.IsMultiline), obj.IsMultiline.ToString());
}
}
現在能正常工作。但問題是當我在我的數據類中有一個像List<Entry>
(其中Entry是另一個數據類)的複雜類型時。
由於IStringFormatter
包含Dictionary<string, string>
,我不能只將List<Entry>
轉換爲字符串,因爲我不知道它在ISerializer
的上下文中想要什麼樣的IStringFormatter
。我怎樣才能解決這個問題?我也想知道我的解決方案是否遵守SOLID原則。如果您可以提出更好的解決方案(不是典型的.NET序列化),我將不勝感激。
這也適用於列表以及?它也有公開獲得,設置屬性 –
是的,它會的。我在我的答案中添加了一個例子。 –
如果我有一個'BitmapSource'(不能序列化)屬性呢? 。我可以將它轉換爲base64,但我怎麼能告訴序列化器做到這一點? –