File: System\Diagnostics\Eventing\TraceLogging\InvokeTypeInfo.cs
Project: ndp\clr\src\bcl\mscorlib.csproj (mscorlib)
using System;
using System.Collections.Generic;
 
#if ES_BUILD_STANDALONE
namespace Microsoft.Diagnostics.Tracing
#else
namespace System.Diagnostics.Tracing
#endif
{
    /// <summary>
    /// TraceLogging: An implementation of TraceLoggingTypeInfo that works
    /// for arbitrary types. It writes all public instance properties of
    /// the type. Implemented using Delegate.CreateDelegate(property.Getter).
    /// </summary>
    /// <typeparam name="ContainerType">
    /// Type from which to read values.
    /// </typeparam>
    internal sealed class InvokeTypeInfo<ContainerType>
        : TraceLoggingTypeInfo<ContainerType>
    {
        private readonly PropertyAnalysis[] properties;
        private readonly PropertyAccessor<ContainerType>[] accessors;
 
        public InvokeTypeInfo(
            TypeAnalysis typeAnalysis)
            : base(
                typeAnalysis.name,
                typeAnalysis.level,
                typeAnalysis.opcode,
                typeAnalysis.keywords,
                typeAnalysis.tags)
        {
            if (typeAnalysis.properties.Length != 0)
            {
                this.properties = typeAnalysis.properties;
                this.accessors = new PropertyAccessor<ContainerType>[this.properties.Length];
                for (int i = 0; i < this.accessors.Length; i++)
                {
                    this.accessors[i] = PropertyAccessor<ContainerType>.Create(this.properties[i]);
                }
            }
        }
 
        public override void WriteMetadata(
            TraceLoggingMetadataCollector collector,
            string name,
            EventFieldFormat format)
        {
            var groupCollector = collector.AddGroup(name);
            if (this.properties != null)
            {
                foreach (var property in this.properties)
                {
                    var propertyFormat = EventFieldFormat.Default;
                    var propertyAttribute = property.fieldAttribute;
                    if (propertyAttribute != null)
                    {
                        groupCollector.Tags = propertyAttribute.Tags;
                        propertyFormat = propertyAttribute.Format;
                    }
 
                    property.typeInfo.WriteMetadata(
                        groupCollector,
                        property.name,
                        propertyFormat);
                }
            }
        }
 
        public override void WriteData(
            TraceLoggingDataCollector collector,
            ref ContainerType value)
        {
            if (this.accessors != null)
            {
                foreach (var accessor in this.accessors)
                {
                    accessor.Write(collector, ref value);
                }
            }
        }
 
        public override object GetData(object value)
        {
            if (this.properties != null)
            {
                var membersNames = new List<string>();
                var memebersValues = new List<object>();
                for (int i = 0; i < this.properties.Length; i++)
                {
                    var propertyValue = accessors[i].GetData((ContainerType)value);
                    membersNames.Add(properties[i].name);
                    memebersValues.Add(properties[i].typeInfo.GetData(propertyValue));
                }
                return new EventPayload(membersNames, memebersValues);
            }
 
            return null;
        }
 
        public override void WriteObjectData(
            TraceLoggingDataCollector collector,
            object valueObj)
        {
            if (this.accessors != null)
            {
                var value = valueObj == null
                    ? default(ContainerType)
                    : (ContainerType)valueObj;
                this.WriteData(collector, ref value);
            }
        }
    }
}