private void CheckEligibleMethods(Aspect aspect) { foreach (var t in this.TypeDefinitions.Where(x => !x.Name.Equals("<Module>") && (x.BaseType == null || (x.BaseType.FullName != typeof(MethodBoundaryAspect).FullName && x.BaseType.FullName != typeof(MethodAroundAspect).FullName)))) { var status = this.CheckAspectStatus(t, aspect); #if DEBUG Console.WriteLine("\t{0}: {1}", t.Name, status.ToString()); #endif if (status == Enums.Status.Excluded) continue; var mths = this.GetMethodDefinitions(t, status, aspect); mths.ForEach(x => { if (!this.EligibleMethods.ContainsKey(x)) { this.EligibleMethods.Add(x, new List<Aspect>() { aspect }); } else { var aspects = this.EligibleMethods[x]; aspects.Add(aspect); } }); } }
private List<MethodDefinition> GetMethodDefinitions(TypeDefinition typeDef, Enums.Status typeStatus, Aspect aspect) { var list = new List<MethodDefinition>(); foreach (var method in typeDef.Methods) { var status = this.CheckAspectStatus(method, aspect); if (status == Enums.Status.Applied) { list.Add(method); } else { if (typeStatus == Enums.Status.Applied && status != Enums.Status.Excluded) { status = Enums.Status.Applied; list.Add(method); } } #if DEBUG Console.WriteLine("\t\t{0}: {1}", method.Name, status.ToString()); #endif } return list; }
/// <summary> /// A TypeDefinition and MethodDefinition both implement the /// ICustomAttributeProvider interface, so it can be used here /// to determined if a method is marked as exclude or not. /// </summary> private Enums.Status CheckAspectStatus(ICustomAttributeProvider def, Aspect aspect) { Enums.Status status = aspect.AssemblyLevelStatus; bool attrFound = false; for (int i = 0; i < def.CustomAttributes.Count; ++i) { if (def.CustomAttributes[i].AttributeType.FullName.Equals("System.Runtime.CompilerServices.CompilerGeneratedAttribute")) { status = Enums.Status.Excluded; break; } if (aspect.TypeDefinition != null && (aspect.BuffaloAspect == Enums.BuffaloAspect.MethodBoundaryAspect || aspect.BuffaloAspect == Enums.BuffaloAspect.MethodAroundAspect) && def.CustomAttributes[i].AttributeType.FullName.Equals(aspect.Name)) { attrFound = true; if (def.CustomAttributes[i].Properties.Count == 0) { status = Enums.Status.Applied; } else { var exclude = def.CustomAttributes[i].Properties.FirstOrDefault(x => x.Name == "AttributeExclude"); if (exclude.Argument.Value != null && (bool)exclude.Argument.Value == true) { status = Enums.Status.Excluded; def.CustomAttributes.RemoveAt(i); } else { status = Enums.Status.Applied; } } } } if (!attrFound && aspect.AssemblyLevelStatus == Enums.Status.Applied) { //this aspect is applied on the assembly level and //as a result the type and method might not have the //attributed annotated, this is to programmatically add //in the annotation so IL can be generated correctly. var ctor = aspect.TypeDefinition.Methods.First(x => x.IsConstructor); var ctoref = this.AssemblyDefinition.MainModule.Import(ctor); def.CustomAttributes.Add(new CustomAttribute(ctoref)); } return status; }