public static void For <T>(EventSourceImplementationAttribute attribute) { if (attribute == null) { throw new ArgumentNullException("attribute"); } _attributes.AddOrUpdate(typeof(T), attribute, (t, a) => a); }
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); }
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; } }