public static void For <T>(EventSourceImplementationAttribute attribute)
        {
            if (attribute == null)
            {
                throw new ArgumentNullException("attribute");
            }

            _attributes.AddOrUpdate(typeof(T), attribute, (t, a) => a);
        }
Beispiel #2
0
        public void TestRenamingInterface()
        {
            EventSourceImplementationAttribute.For <IHateThisName>(new EventSourceImplementationAttribute()
            {
                Name = "A Better Name"
            });
            var logger = EventSourceImplementer.GetEventSourceAs <IHateThisName>();

            Assert.AreEqual("A Better Name", ((EventSource)logger).Name);
        }
        /// <summary>
        /// Copies the EventSourceAttribute from the interfaceType to a CustomAttributeBuilder.
        /// </summary>
        /// <param name="type">The interfaceType to copy.</param>
        /// <returns>A CustomAttributeBuilder that can be assigned to a type.</returns>
        internal static CustomAttributeBuilder GetEventSourceAttributeBuilder(Type type)
        {
            var attribute      = type.GetTypeInfo().GetCustomAttribute <EventSourceAttribute>() ?? new EventSourceAttribute();
            var implementation = EventSourceImplementationAttribute.GetAttributeFor(type);

            // by default, we will use a null guid, which will tell EventSource to generate the guid from the name
            // but if we have already generated this type, we will have to generate a new one
            string guid = implementation.Guid ?? attribute.Guid ?? null;

            if (guid == null)
            {
                lock (_typesImplemented)
                {
                    if (_typesImplemented.Contains(type))
                    {
                        guid = Guid.NewGuid().ToString();
                    }
                    else
                    {
                        _typesImplemented.Add(type);
                    }
                }
            }

            var propertyValues = new object[]
            {
                implementation.Name ?? attribute.Name ?? (type.GetTypeInfo().IsGenericType ? type.FullName : type.Name),
                guid,
                implementation.LocalizationResources ?? attribute.LocalizationResources ?? null
            };

            CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(
                _eventSourceAttributeConstructor,
                _emptyParameters,
                _eventSourceAttributePropertyInfo,
                propertyValues);

            return(attributeBuilder);
        }
Beispiel #4
0
        private void ImplementType()
        {
            // create a new assembly
            AssemblyName an = Assembly.GetExecutingAssembly().GetName();

            an.Name = ProxyHelper.AssemblyName;
            AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
            ModuleBuilder   mb = ab.DefineDynamicModule(an.Name);

            // create a type based on EventSource and call the default constructor
            if (_interfaceType.IsSubclassOf(typeof(EventSource)))
            {
                _typeBuilder = mb.DefineType(_interfaceType.FullName + "_Implemented", TypeAttributes.Class | TypeAttributes.Public, _interfaceType);
            }
            else if (_interfaceType.IsInterface)
            {
                _typeBuilder = mb.DefineType(_interfaceType.FullName + "_Implemented", TypeAttributes.Class | TypeAttributes.Public, typeof(EventSource), new Type[] { _interfaceType });
            }
            else
            {
                _typeBuilder = mb.DefineType(_interfaceType.FullName + "_Implemented", TypeAttributes.Class | TypeAttributes.Public, typeof(EventSource));
            }

            var implementationAttribute = EventSourceImplementationAttribute.GetAttributeFor(_interfaceType);

            // add the constructor that calls the base with throwOnEventWriteErrors:
            var baseCtor = typeof(EventSource).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(bool) }, null);

            var emitter = _typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard | CallingConventions.HasThis, new Type[0]).GetILGenerator();

            emitter.Emit(OpCodes.Ldarg_0);
            emitter.Emit(implementationAttribute.ThrowOnEventWriteErrors ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
            emitter.Emit(OpCodes.Call, baseCtor);
            emitter.Emit(OpCodes.Nop);
            emitter.Emit(OpCodes.Nop);
            emitter.Emit(OpCodes.Ret);

            // assign an EventSource attribute to the type so it gets the original name and guid
            _typeBuilder.SetCustomAttribute(EventSourceAttributeHelper.GetEventSourceAttributeBuilder(_interfaceType));

            // implement the fields and constructor
            EmitFields();

            // find all of the methods that need to be implemented
            var interfaceMethods = ProxyHelper.DiscoverMethods(_interfaceType);

            // find the first free event id, in case we need to assign some ourselves
            int eventId = interfaceMethods
                          .Select(m => m.GetCustomAttribute <EventAttribute>())
                          .Where(a => a != null)
                          .Select(a => a.EventId)
                          .DefaultIfEmpty(0)
                          .Max() + 1;

            // if there isn't a keyword class, then auto-generate the keywords
            bool  hasAutoKeywords = implementationAttribute.AutoKeywords || EventSourceImplementer.ForceAutoKeywords;
            bool  hasKeywords     = (implementationAttribute.Keywords != null) || (FindNestedType(_interfaceType, "Keywords") != null);
            ulong nextAutoKeyword = hasKeywords ? (ulong)0 : 1;

            // for each method on the interface, try to implement it with a call to eventsource
            Dictionary <string, ulong> autoKeywords = new Dictionary <string, ulong>();

            foreach (MethodInfo interfaceMethod in interfaceMethods)
            {
                var invocationContext = new InvocationContext(interfaceMethod, InvocationContextTypes.MethodCall);

                // determine the keyword to use for the method
                string keywordName = FoldMethodName(interfaceMethod);
                if (!autoKeywords.ContainsKey(keywordName))
                {
                    autoKeywords.Add(keywordName, nextAutoKeyword);

                    // shift to the next keyword
                    nextAutoKeyword <<= 1;

                    // System.ArgumentException: Keywords values larger than 0x0000100000000000 are reserved for system use
                    // so we have to stop generating autokeywords
                    if (nextAutoKeyword >= ReservedKeywordValue)
                    {
                        nextAutoKeyword = 0;
                    }
                }

                ulong keywordForMethod = hasAutoKeywords ? autoKeywords[keywordName] : 0;

                // emit the method
                var beginMethod = EmitMethodImpl(invocationContext, ref eventId, (EventKeywords)keywordForMethod);

                // if we are generating an interface, add the complement methods
                if (implementationAttribute.ImplementComplementMethods && !_interfaceType.IsSubclassOf(typeof(EventSource)))
                {
                    var faultedMethod = EmitMethodFaultedImpl(invocationContext, beginMethod, ref eventId, (EventKeywords)keywordForMethod);
                    EmitMethodCompletedImpl(invocationContext, beginMethod, ref eventId, (EventKeywords)keywordForMethod, faultedMethod);
                }
            }

            // create the type
            Type t = _typeBuilder.CreateType();

            // define the internal enum classes if they are defined
            if (hasKeywords)
            {
                EmitEnumImplementation(implementationAttribute.Keywords, Keywords, typeof(EventKeywords));
            }
            else if (hasAutoKeywords)
            {
                EmitKeywordImpl(autoKeywords);
            }
            EmitEnumImplementation(implementationAttribute.OpCodes, Opcodes, typeof(EventOpcode));
            EmitEnumImplementation(implementationAttribute.Tasks, Tasks, typeof(EventTask));

            // initialize the static fields
            t.GetField(_invocationContextsField.Name, BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, _invocationContexts.ToArray());
            t.GetField(_serializationProviderField.Name, BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, _serializationProvider);
            t.GetField(_contextProviderField.Name, BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, _contextProvider);

            // instantiate the singleton
            EventSource = (EventSource)t.GetConstructor(Type.EmptyTypes).Invoke(null);

            // fill in the event source for all of the invocation contexts
            foreach (var context in _invocationContexts)
            {
                context.EventSource = EventSource;
            }
        }