示例#1
0
        /// <summary>
        /// Registers the dump metadata and <see cref="DumpAttribute" /> instance related to the specified type.
        /// </summary>
        /// <param name="type">The type for which the metadata is being registered.</param>
        /// <param name="metadataType">The dump metadata type.</param>
        /// <param name="dumpAttribute">The dump attribute.</param>
        /// <param name="replace">
        /// If set to <see langword="false" /> and there is already dump metadata associated with the <paramref name="type"/>
        /// the method will throw exception of type <see cref="InvalidOperationException"/>;
        /// otherwise it will silently override the existing metadata with <paramref name="metadataType"/> and <paramref name="dumpAttribute"/>.
        /// </param>
        /// <returns>The current instance of ClassMetadataRegistrar.</returns>
        /// <exception cref="T:System.ArgumentNullException">Thrown if <paramref name="type" /> is <see langword="null" />.</exception>
        /// <exception cref="InvalidOperationException">
        /// Thrown if <paramref name="replace"/> is <see langword="false"/> and there is already metadata associated with the <paramref name="type"/>.
        /// </exception>
        public ClassMetadataRegistrar Register(
            Type type,
            Type metadataType,
            DumpAttribute dumpAttribute = null,
            bool replace = false)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            ClassMetadataResolver.SetClassDumpData(type, metadataType, dumpAttribute, replace);
            return(this);
        }
示例#2
0
        /// <summary>
        /// Registers the metadata defined in <see cref="ExternalMetadata"/>.
        /// Allows for chaining further registering more dump metadata.
        /// </summary>
        /// <returns>ClassMetadataRegistrar.</returns>
        public static ClassMetadataRegistrar RegisterMetadata()
        {
            ClassMetadataResolver.SetClassDumpData(typeof(Task <>), typeof(TaskGenericDumpMetadata));

            return(new ClassMetadataRegistrar()
                   .Register <Type, TypeDumpMetadata>()
                   .Register <Exception, ExceptionDumpMetadata>()
                   .Register <ArgumentException, ArgumentExceptionDumpMetadata>()
                   .Register <SecurityException, SecurityExceptionDumpMetadata>()
                   .Register <CultureInfo, CultureInfoDumpMetadata>()
                   .Register <Task, TaskDumpMetadata>()
                   .Register <ClaimsIdentity, ClaimsIdentityMetadata>()
                   .Register <Claim, ClaimMetadata>()

                   .Register <Expression, ExpressionDumpMetadata>()
                   .Register <LambdaExpression, LambdaExpressionDumpMetadata>()
                   .Register <ParameterExpression, ParameterExpressionDumpMetadata>()
                   .Register <BinaryExpression, BinaryExpressionDumpMetadata>()
                   .Register <ConstantExpression, ConstantExpressionDumpMetadata>()
                   );

            // Do not extend the BCL dependency, but the client can call also:
            //
            //using System.Data;
            //using System.Data.Metadata.Edm;
            //using System.Data.SqlClient;
            //using System.Net;
            //using Microsoft.Practices.EnterpriseLibrary.Validation;
            //using Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection;
            //
            //.Register<SqlException, SqlExceptionDumpMetadata>()
            //.Register<SqlError, SqlErrorDumpMetadata>()
            //.Register<ArgumentValidationException, ArgumentValidationExceptionDumpMetadata>()
            //.Register<MetadataItem, MetadataItemDumpMetadata>()
            //.Register<UpdateException, UpdateExceptionDumpMetadata>()
            //.Register<ValidationResult, ValidationResultDumpMetadata>()
            //.Register<ValidationResults, ValidationResultsDumpMetadata>()
            //.Register<ConfigurationErrorsException, ConfigurationErrorsExceptionDumpMetadata>()
            //.Register<WebException, WebExceptionDumpMetadata>()
            ;
        }
示例#3
0
        internal void DumpObject(
            object obj,
            Type dumpMetadata           = null,
            DumpAttribute dumpAttribute = null,
            DumpState parentState       = null)
        {
            if (Writer.DumpedBasicValue(obj, dumpAttribute) || Writer.DumpedBasicNullable(obj, dumpAttribute))      // incl. null
            {
                return;
            }

            // resolve the class metadata and the dump attribute
            ClassDumpData classDumpData;
            var           objectType = obj.GetType();

            if (dumpMetadata == null)
            {
                classDumpData = ClassMetadataResolver.GetClassDumpData(objectType);
                if (dumpAttribute != null)
                {
                    classDumpData.DumpAttribute = dumpAttribute;
                }
            }
            else
            {
                classDumpData = new ClassDumpData(dumpMetadata, dumpAttribute);
            }

            // if we're too deep - stop here.
            if (_maxDepth == int.MinValue)
            {
                _maxDepth = classDumpData.DumpAttribute.MaxDepth;
            }

            if (_maxDepth < 0)
            {
                Writer.Write(Resources.DumpReachedMaxDepth);
                return;
            }

            // save here the IsSubExpression flag as it will change if obj is Expression and IsSubExpression==false.
            // but in the end of this method restore the value from this local variable. See below.
            var isSubExpressionStore = IsSubExpression;

            // slow dump vs. run script?
            bool   isTopLevelObject = parentState == null;
            var    buildScript      = UseDumpScriptCache && !obj.IsDynamicObject();
            Script script           = null;

            using (var state = new DumpState(this, obj, classDumpData, buildScript))
            {
                if (buildScript)
                {
                    // does the script exist or is it in process of building
                    if (DumpScriptCache.TryFind(this, obj, classDumpData, out script))
                    {
                        if (script != null)
                        {
                            if (isTopLevelObject)
                            {
                                Writer.Indent(_indentLevel, _indentSize)
                                .WriteLine();
                            }

                            script(obj, classDumpData, this, state);
                        }

                        return;
                    }

                    DumpScriptCache.BuildingScriptFor(this, objectType, classDumpData);
                }
                else
                {
                    if (isTopLevelObject)
                    {
                        Writer.Indent(_indentLevel, _indentSize)
                        .WriteLine();
                    }
                }

                if (!state.DumpedAlready())     // the object has been dumped already (block circular and repeating references)
                {
                    // this object will be dumped below.
                    // Add it to the dumped objects now so that if nested property refers back to it, it won't be dumped in an infinite recursive chain.
                    DumpedObjects.Add(new DumpedObject(obj, objectType));

                    if (!state.DumpedCollection(classDumpData.DumpAttribute, false))   // custom collections are dumped after dumping all other properties (see below *  )
                    {
                        Stack <DumpState> statesWithRemainingProperties = new Stack <DumpState>();
                        Queue <DumpState> statesWithTailProperties      = new Queue <DumpState>();

                        // recursively dump all properties with non-negative order in class inheritance descending order (base classes' properties first)
                        // and if there are more properties  to be dumped put them in the stack
                        if (!DumpedTopProperties(state, statesWithRemainingProperties))
                        {
                            // dump all properties with negative order in class ascending order (derived classes' properties first)
                            DumpRemainingProperties(statesWithRemainingProperties, statesWithTailProperties);

                            // dump all properties with Order=int.MinValue in ascending order (derived classes' properties first)
                            DumpTailProperties(statesWithTailProperties);

                            // * if the object implements IEnumerable and the state allows it - dump the elements.
                            state.DumpedCollection(classDumpData.DumpAttribute, true);
                        }

                        // we are done dumping
                        state.Unindent();
                    }
                }

                if (buildScript && state.DumpScript != null)
                {
                    script = DumpScriptCache.Add(this, objectType, classDumpData, state.DumpScript);
                }

                if (!buildScript)
                {
                    if (isTopLevelObject)
                    {
                        Writer.Unindent(_indentLevel, _indentSize);
                    }
                }
                else
                {
                    if (script != null)
                    {
                        if (isTopLevelObject)
                        {
                            Writer.Indent(_indentLevel, _indentSize)
                            .WriteLine();
                        }

                        script(obj, classDumpData, this, state);
                    }
                }

                // restore here the IsSubExpression flag as it have changed if obj is Expression and IsSubExpression==false.
                IsSubExpression = isSubExpressionStore;
            }
        }