123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- using System;
- using System.Collections.Concurrent;
- using System.Linq;
- using System.Linq.Expressions;
- using System.Reflection;
- using Newtonsoft.Json;
- namespace VCommon.VAutoMapper.Internals
- {
- internal static class JsonConvertHolder
- {
- private static readonly ConcurrentDictionary<Type, JsonConverter> ConverterInstances = new ConcurrentDictionary<Type, JsonConverter>();
- private static readonly ConcurrentDictionary<Tuple<PropertyInfo, PropertyInfo>, Expression<Func<string, Type, object>>> CachedDeserializationExpression = new ConcurrentDictionary<Tuple<PropertyInfo, PropertyInfo>, Expression<Func<string, Type, object>>>();
- private static readonly ConcurrentDictionary<Tuple<PropertyInfo, PropertyInfo>, Expression<Func<object, string>>> CachedSerializationExpression = new ConcurrentDictionary<Tuple<PropertyInfo, PropertyInfo>, Expression<Func<object, string>>>();
- private static JsonConverter GetConverterInstance(Type converterType)
- {
- if (ConverterInstances.TryGetValue(converterType, out var instance)) return instance;
- instance = Activator.CreateInstance(converterType) as JsonConverter;
- ConverterInstances[converterType] = instance ?? throw new ArgumentException($"type must extend from {nameof(JsonConverter)}");
- return instance;
- }
- public static Expression<Func<string, Type, object>> GetDeserializationExpression(PropertyInfo fromProp, PropertyInfo toProp)
- {
- var pair = new Tuple<PropertyInfo, PropertyInfo>(fromProp, toProp);
- if (CachedDeserializationExpression.TryGetValue(pair, out var exp)) return exp;
- var attr = toProp.GetCustomAttribute<AutoMapJsonConvertAttribute>();
- if (0 == attr.Converters.Count)
- {
- exp = (s, t) => JsonConvert.DeserializeObject(s, t);
- CachedDeserializationExpression[pair] = exp;
- }
- else
- {
- var converters = attr.Converters.Select(GetConverterInstance).ToArray();
- var setting = new JsonSerializerSettings { Converters = converters };
- exp = CachedDeserializationExpression[pair] = (s, t) => JsonConvert.DeserializeObject(s, t, setting);
- }
- return exp;
- }
- public static Expression<Func<object, string>> GetSerializationExpression(PropertyInfo fromProp, PropertyInfo toProp)
- {
- var pair = new Tuple<PropertyInfo, PropertyInfo>(fromProp, toProp);
- if (CachedSerializationExpression.TryGetValue(pair, out var exp)) return exp;
- var attr = fromProp.GetCustomAttribute<AutoMapJsonConvertAttribute>();
- if (0 == attr.Converters.Count)
- {
- exp = CachedSerializationExpression[pair] = o => JsonConvert.SerializeObject(o);
- }
- else
- {
- var converters = attr.Converters.Select(GetConverterInstance).ToArray();
- var setting = new JsonSerializerSettings { Converters = converters };
- exp = CachedSerializationExpression[pair] = o => JsonConvert.SerializeObject(o, setting);
- }
- return exp;
- }
- }
- }
|