/// <summary> /// Create a new instance of <see cref="MessageParameterResolver"/>. /// </summary> /// <param name="maxLengthOfString"></param> /// <param name="maxLevelOfNestLevelLimited"></param> /// <param name="maxLoopCountForCollection"></param> /// <param name="additionalScalarTypes"></param> /// <param name="additionalDestructureResolveRules"></param> /// <param name="raiseExceptions"></param> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="ArgumentNullException"></exception> public MessageParameterResolver( int maxLengthOfString, int maxLevelOfNestLevelLimited, int maxLoopCountForCollection, IEnumerable <Type> additionalScalarTypes, IEnumerable <IDestructureResolveRule> additionalDestructureResolveRules, bool raiseExceptions) { if (maxLengthOfString < 2) { throw new ArgumentOutOfRangeException(nameof(maxLengthOfString)); } if (maxLevelOfNestLevelLimited < 0) { throw new ArgumentOutOfRangeException(nameof(maxLevelOfNestLevelLimited)); } if (maxLoopCountForCollection < 1) { throw new ArgumentOutOfRangeException(nameof(maxLoopCountForCollection)); } if (additionalScalarTypes == null) { throw new ArgumentNullException(nameof(additionalScalarTypes)); } if (additionalDestructureResolveRules == null) { throw new ArgumentNullException(nameof(additionalDestructureResolveRules)); } _maxLengthOfString = maxLengthOfString; _maxLevelOfNestLevelLimited = maxLevelOfNestLevelLimited; _maxLoopCountForCollection = maxLoopCountForCollection; _raiseExceptions = raiseExceptions; _scalarResolveRules = new IScalarResolveRule[] { new SimpleResolveRule(additionalScalarTypes.GetAllScalarTypes()), new EnumResolveRule(), new ByteArrayResolveRule() }; _destructureResolveRules = additionalDestructureResolveRules .Concat(new IDestructureResolveRule[] { new DelegateResolveRule(), new ReflectionTypesResolveRule() }) .ToArray(); _nestParameterResolver = new NestParameterResolver(_maxLevelOfNestLevelLimited, this); }
public static bool TryResolveCompilerGeneratedType(object value, PropertyResolvingMode mode, NestParameterResolver nest, Type typeOfValue, bool raiseException, int positionalValue, out MessagePropertyValue result) { if (mode == PropertyResolvingMode.Destructure) { result = new StructureValue(StructureElements(), Tag()); return(true); string Tag() { var __tag = typeOfValue.Name; if (string.IsNullOrWhiteSpace(__tag) || typeOfValue.IsCompilerGeneratedType()) { __tag = null; } return(__tag); } IEnumerable <MessageProperty> StructureElements() { foreach (var property in value.GetType().GetPropertiesRecursive()) { dynamic propertyValue; try { propertyValue = property.GetValue(value); } catch (TargetParameterCountException) { InternalLogger.WriteLine("The property accessor '{0}' is a non-default indexer", property); continue; } catch (TargetInvocationException ex) { InternalLogger.WriteLine("The property accessor '{0}' threw exception: {1}", property, ex); if (raiseException) { throw; } propertyValue = $"Threw an exception at: {ex.InnerException?.GetType().Name}"; } yield return(new MessageProperty(property.Name, positionalValue, nest.CreatePropertyValue(propertyValue, PropertyResolvingMode.Destructure))); } } } result = null; return(false); }
public static bool TryResolveToValueTuple(object value, PropertyResolvingMode mode, NestParameterResolver nest, Type typeOfValue, out MessagePropertyValue result) { result = CheckingValueTypeDefinition(typeOfValue, value) ? new SequenceValue(SequenceElements()) : null; return(result != null); IEnumerable <MessagePropertyValue> SequenceElements() { var __fields = typeOfValue.GetTypeInfo().DeclaredFields.Where(f => f.IsPublic && !f.IsStatic); foreach (var __field in __fields) { yield return(nest.CreatePropertyValue(__field.GetValue(value), mode)); } } }
public static bool TryResolveToEnumerable(object value, PropertyResolvingMode mode, NestParameterResolver nest, Type typeOfValue, int maxLoopCountForCollection, out MessagePropertyValue result) { if (value is IEnumerable __enumerable) { if (TryGetDictionary(value, typeOfValue, out var dictionary)) { result = new DictionaryValue(DictionaryElements()); return(true); IEnumerable <KeyValuePair <ScalarValue, MessagePropertyValue> > DictionaryElements() { var __index = 0; foreach (DictionaryEntry __item in dictionary) { if (++__index > maxLoopCountForCollection) { yield break; } if (nest.CreatePropertyValue(__item.Key, mode) is ScalarValue __key) { var __value = nest.CreatePropertyValue(__item.Value, mode); yield return(new KeyValuePair <ScalarValue, MessagePropertyValue>(__key, __value)); } } } } result = new SequenceValue(SequenceElements()); return(true); IEnumerable <MessagePropertyValue> SequenceElements() { var __index = 0; foreach (var __item in __enumerable) { if (++__index > maxLoopCountForCollection) { yield break; } yield return(nest.CreatePropertyValue(__item, mode)); } } } result = null; return(false); }