private static bool TryLookupExtractor(ExtractorDictionary stateExractor, Type propertyType,
                                                   out KeyValuePair <Func <object, object>, Func <object, object> > keyValueExtractor)
            {
                if (!stateExractor.TryGetValue(propertyType, out keyValueExtractor))
                {
                    try
                    {
                        return(TryBuildExtractor(propertyType, out keyValueExtractor));
                    }
                    catch (Exception ex)
                    {
                        InternalLogger.Debug(ex, "Exception in BeginScope create property extractor");
                    }
                    finally
                    {
                        stateExractor[propertyType] = keyValueExtractor;
                    }
                }

                return(keyValueExtractor.Key != null);
            }
            public static IDisposable CaptureScopeProperties(IEnumerable scopePropertyCollection, ExtractorDictionary stateExractor)
            {
                List <KeyValuePair <string, object> > propertyList = null;

                var keyValueExtractor = default(KeyValuePair <Func <object, object>, Func <object, object> >);

                foreach (var property in scopePropertyCollection)
                {
                    if (property == null)
                    {
                        break;
                    }

                    if (keyValueExtractor.Key == null && !TryLookupExtractor(stateExractor, property.GetType(), out keyValueExtractor))
                    {
                        break;
                    }

                    var propertyValue = TryParseKeyValueProperty(keyValueExtractor, property);
                    if (!propertyValue.HasValue)
                    {
                        continue;
                    }

                    propertyList = propertyList ?? new List <KeyValuePair <string, object> >();
                    propertyList.Add(propertyValue.Value);
                }

                return(CreateScopeProperties(scopePropertyCollection, propertyList));
            }
            public static IDisposable CaptureScopeProperty <TState>(TState scopeProperty, ExtractorDictionary stateExractor)
            {
                if (!TryLookupExtractor(stateExractor, scopeProperty.GetType(), out var keyValueExtractor))
                {
                    return(NestedDiagnosticsLogicalContext.Push(scopeProperty));
                }

                var propertyValue = TryParseKeyValueProperty(keyValueExtractor, scopeProperty);

                if (!propertyValue.HasValue)
                {
                    return(NestedDiagnosticsLogicalContext.Push(scopeProperty));
                }

                return(new ScopeProperties(NestedDiagnosticsLogicalContext.Push(scopeProperty), MappedDiagnosticsLogicalContext.SetScoped(propertyValue.Value.Key, propertyValue.Value.Value)));
            }
        public static IDisposable CaptureScopeProperty <TState>(TState scopeProperty, ExtractorDictionary stateExtractor)
        {
            if (!TryLookupExtractor(stateExtractor, scopeProperty.GetType(), out var keyValueExtractor))
            {
                return(ScopeContext.PushNestedState(scopeProperty));
            }

            object scopePropertyValue = scopeProperty;
            var    propertyValue      = TryParseKeyValueProperty(keyValueExtractor, scopePropertyValue);

            if (propertyValue.HasValue)
            {
                return(ScopeContext.PushNestedStateProperties(scopePropertyValue, new[] { new KeyValuePair <string, object>(propertyValue.Value.Key, propertyValue.Value.Value) }));
            }

            return(ScopeContext.PushNestedState(scopeProperty));
        }