using MessagePack; namespace XFEExtension.NetCore.AutoConfig; internal static class MessagePackProfileSerializer { private static readonly MessagePackSerializerOptions DocumentOptions = MessagePackSerializerOptions.Standard .WithSecurity(MessagePackSecurity.UntrustedData); public static byte[] Serialize( XFEProfile profile, IReadOnlyDictionary propertyTypes, IReadOnlyDictionary propertyGetters, int version) { var properties = new Dictionary(propertyGetters.Count, StringComparer.Ordinal); foreach (var property in propertyGetters) { if (!propertyTypes.TryGetValue(property.Key, out var propertyType)) throw new InvalidOperationException($"未找到配置属性“{property.Key}”的类型信息"); properties.Add(property.Key, MessagePackSerializer.Serialize(propertyType, property.Value(), profile.MessagePackOptions)); } return MessagePackSerializer.Serialize( new MessagePackProfileDocument { Version = version, Properties = properties }, DocumentOptions); } public static MessagePackProfileDocument Deserialize(ReadOnlyMemory content) { var document = MessagePackSerializer.Deserialize(content, DocumentOptions) ?? throw new MessagePackSerializationException("MessagePack 配置文档为空"); document.Properties ??= new Dictionary(StringComparer.Ordinal); return document; } public static void Populate( XFEProfile profile, IReadOnlyDictionary properties, IReadOnlyDictionary propertyTypes, IReadOnlyDictionary propertySetters) { foreach (var property in properties) { if (!propertyTypes.TryGetValue(property.Key, out var propertyType) || !propertySetters.TryGetValue(property.Key, out var setter)) continue; setter(MessagePackSerializer.Deserialize(propertyType, property.Value, profile.MessagePackOptions)); } } } [MessagePackObject(AllowPrivate = true)] internal sealed class MessagePackProfileDocument { [Key(0)] public int Version { get; set; } [Key(1)] public Dictionary Properties { get; set; } = new(StringComparer.Ordinal); }