public void ProvideAdvices(PostSharp.CodeWeaver.Weaver codeWeaver) { // Gets the dictionary of custom attributes. CustomAttributeDictionaryTask customAttributeDictionary = CustomAttributeDictionaryTask.GetTask(this.Project); // Requests an enumerator of all instances of our Singleton. IEnumerator<ICustomAttributeInstance> customAttributeEnumerator = customAttributeDictionary.GetCustomAttributesEnumerator(typeof(SingletonAttribute), true); ICollection<TypeDefDeclaration> singletons = new HashSet<TypeDefDeclaration>(); // For each instance of our Singleton. while (customAttributeEnumerator.MoveNext()) { // Gets the type to which it applies. TypeDefDeclaration typeDef = customAttributeEnumerator.Current.TargetElement as TypeDefDeclaration; if (typeDef != null && !singletons.Contains(typeDef)) { singletons.Add(typeDef); codeWeaver.AddTypeLevelAdvice(new SingletonAccessorAdvice(typeDef), JoinPointKinds.BeforeStaticConstructor, new Singleton<TypeDefDeclaration>(typeDef)); codeWeaver.AddMethodLevelAdvice(new SingletonAdvice(typeDef), null, JoinPointKinds.InsteadOfNewObject, new Singleton<MetadataDeclaration>(typeDef.Methods.GetOneByName(".ctor"))); } } singletons.Clear(); foreach(AssemblyRefDeclaration assembly in this.Project.Module.AssemblyRefs) { foreach (TypeRefDeclaration type in assembly.TypeRefs) { TypeDefDeclaration def = type.GetTypeDefinition(); foreach(CustomAttributeDeclaration att in def.CustomAttributes) { if (Object.Equals(att.Constructor.DeclaringType.GetSystemType(new Type[]{},new Type[]{}), typeof(SingletonAttribute))) { singletons.Add(def); } } } } foreach(TypeDefDeclaration type in singletons) { codeWeaver.AddMethodLevelAdvice(new SingletonAdvice(type), null, JoinPointKinds.InsteadOfNewObject, new Singleton<MetadataDeclaration>(type.Methods.GetOneByName(".ctor"))); } }
public void ProvideAdvices(PostSharp.Sdk.CodeWeaver.Weaver codeWeaver) { LogInitializeAdvice.InitializeLoggerPolicies(this); // Gets the dictionary of custom attributes. var customAttributeDictionaryTask = AnnotationRepositoryTask.GetTask(this.Project); // Requests an enumerator of all instances of the LogAttribute. var customAttributeEnumerator = customAttributeDictionaryTask.GetAnnotationsOfType(typeof(LogAttribute), false); // For each instance of the LogAttribute. while (customAttributeEnumerator.MoveNext()) { // Gets the method to which it applies. MethodDefDeclaration methodDef = customAttributeEnumerator.Current.TargetElement as MethodDefDeclaration; if (methodDef != null) { // Type whose constructor is being woven. TypeDefDeclaration wovenType = methodDef.DeclaringType; // Do not weave interface. if ((wovenType.Attributes & TypeAttributes.Interface) != TypeAttributes.Interface) { // Constructs a custom attribute instance. LogAttribute attribute = (LogAttribute)CustomAttributeHelper.ConstructRuntimeObject(customAttributeEnumerator.Current.Value); bool isMethodEligibleForInjection; if (attribute.IncludeCompilerGeneratedCode) { // Logging code can be injected even if the method is compiler generated. // Method processing can safely continue. isMethodEligibleForInjection = true; } else { // Proceed with the method only when it is not compiler generated and // its declaring type is not generated. isMethodEligibleForInjection = !(methodDef.CustomAttributes.Contains(this.compilerGeneratedAttributeType) || methodDef.DeclaringType.CustomAttributes.Contains(this.compilerGeneratedAttributeType)); } if (isMethodEligibleForInjection) { // Build an advice based on this custom attribute. LogAdvice advice = new LogAdvice(this, attribute); // Join point kinds that are used by respective logging code. JoinPointKinds enterKinds = (attribute.EntryLevel != LogLevel.None) ? JoinPointKinds.BeforeMethodBody : 0; JoinPointKinds exitKinds = (attribute.ExitLevel != LogLevel.None) ? JoinPointKinds.AfterMethodBodySuccess : 0; JoinPointKinds exceptionKinds = (attribute.ExceptionLevel != LogLevel.None) ? JoinPointKinds.AfterMethodBodyException : 0; // Sum of all required join point kinds; JoinPointKinds effectiveKinds = enterKinds | exitKinds | exceptionKinds; // Ensure there is at least one join point the logging advice applies to. if (effectiveKinds != 0) { if (!this.perTypeLoggingDatas.ContainsKey(wovenType)) { AddTypeLogginData(wovenType); codeWeaver.AddTypeLevelAdvice(new LogInitializeAdvice(this), JoinPointKinds.BeforeStaticConstructor, new Singleton<TypeDefDeclaration>(wovenType)); } codeWeaver.AddMethodLevelAdvice(advice, new Singleton<MethodDefDeclaration>(methodDef), effectiveKinds, null); } } } } } //Check for types having LoggerAttribute and have no LogAttribute. customAttributeEnumerator = customAttributeDictionaryTask.GetAnnotationsOfType(typeof(LoggerAttribute), false); while (customAttributeEnumerator.MoveNext()) { // Gets the method to which it applies. TypeDefDeclaration wovenType = customAttributeEnumerator.Current.TargetElement as TypeDefDeclaration; if (wovenType != null && !perTypeLoggingDatas.ContainsKey(wovenType)) { //Weave AddTypeLogginData(wovenType); codeWeaver.AddTypeLevelAdvice(new LogInitializeAdvice(this), JoinPointKinds.BeforeStaticConstructor, new Singleton<TypeDefDeclaration>(wovenType)); } } //Check for types compatible to LoggerPolicyAttribute and have no LogAttribute. customAttributeEnumerator = customAttributeDictionaryTask.GetAnnotationsOfType(typeof(LoggerPolicyAttribute), false); while (customAttributeEnumerator.MoveNext()) { // Gets the method to which it applies. TypeDefDeclaration wovenType = customAttributeEnumerator.Current.TargetElement as TypeDefDeclaration; if (wovenType != null && !wovenType.IsModuleSpecialType && !perTypeLoggingDatas.ContainsKey(wovenType)) { //Weave AddTypeLogginData(wovenType); codeWeaver.AddTypeLevelAdvice(new LogInitializeAdvice(this), JoinPointKinds.BeforeStaticConstructor, new Singleton<TypeDefDeclaration>(wovenType)); } } }
public void ProvideAdvices(PostSharp.CodeWeaver.Weaver codeWeaver) { // Gets the dictionary of custom attributes. CustomAttributeDictionaryTask customAttributeDictionaryTask = CustomAttributeDictionaryTask.GetTask(this.Project); // Requests an enumerator of all instances of the LogAttribute. IEnumerator<ICustomAttributeInstance> customAttributeEnumerator = customAttributeDictionaryTask.GetCustomAttributesEnumerator(typeof (LogAttribute), false); // For each instance of the LogAttribute. while (customAttributeEnumerator.MoveNext()) { // Gets the method to which it applies. MethodDefDeclaration methodDef = customAttributeEnumerator.Current.TargetElement as MethodDefDeclaration; if (methodDef != null) { // Type whose constructor is being woven. TypeDefDeclaration wovenType = methodDef.DeclaringType; // Do not weave interface. if ((wovenType.Attributes & TypeAttributes.Interface) != TypeAttributes.Interface) { // Constructs a custom attribute instance. LogAttribute attribute = (LogAttribute) CustomAttributeHelper.ConstructRuntimeObject(customAttributeEnumerator.Current.Value, this.Project.Module); bool isMethodEligibleForInjection; if (attribute.IncludeCompilerGeneratedCode) { // Logging code can be injected even if the method is compiler generated. // Method processing can safely continue. isMethodEligibleForInjection = true; } else { // Proceed with the method only when it is not compiler generated and // its declaring type is not generated. isMethodEligibleForInjection = ! (methodDef.CustomAttributes.Contains(this.compilerGeneratedAttributeType) || methodDef.DeclaringType.CustomAttributes.Contains(this.compilerGeneratedAttributeType)); } if (isMethodEligibleForInjection) { // Build an advice based on this custom attribute. LogAdvice advice = new LogAdvice(this, attribute); // Join point kinds that are used by respective logging code. JoinPointKinds enterKinds = (attribute.EntryLevel != LogLevel.None) ? JoinPointKinds.BeforeMethodBody : 0; JoinPointKinds exitKinds = (attribute.ExitLevel != LogLevel.None) ? JoinPointKinds.AfterMethodBodySuccess : 0; JoinPointKinds exceptionKinds = (attribute.ExceptionLevel != LogLevel.None) ? JoinPointKinds.AfterMethodBodyException : 0; // Sum of all required join point kinds; JoinPointKinds effectiveKinds = enterKinds | exitKinds | exceptionKinds; // Ensure there is at least one join point the logging advice applies to. if (effectiveKinds != 0) { if (!this.perTypeLoggingDatas.ContainsKey(wovenType)) { this.perTypeLoggingDatas.Add(wovenType, new PerTypeLoggingData()); // Logging data for the woven type. PerTypeLoggingData perTypeLoggingData = this.perTypeLoggingDatas[wovenType]; // Field where ILog instance is stored. FieldDefDeclaration logField = CreateField("~log4PostSharp~log", this.ilogType); wovenType.Fields.Add(logField); perTypeLoggingData.Log = logField; codeWeaver.AddTypeLevelAdvice(new LogInitializeAdvice(this), JoinPointKinds.BeforeStaticConstructor, new Singleton<TypeDefDeclaration>(wovenType)); } codeWeaver.AddMethodLevelAdvice(advice, new Singleton<MethodDefDeclaration>(methodDef), effectiveKinds, null); } } } } } }