private void InjectInitialization(TargetMethodContext initMethod, FieldDefinition field, MethodDefinition factoryMethod) { if (!field.IsStatic) { initMethod.EntryPoint.LoadSelfOntoStack(); } initMethod.EntryPoint.LoadField(field); initMethod.EntryPoint.TestValueOnStack((object)null, trueBlock => { if (!field.IsStatic) { trueBlock.LoadSelfOntoStack(); } trueBlock.SetField(field, c => { c.InjectMethodCall(factoryMethod, new object[] { }); }); }); }
public FieldReference GetOrCreateAspectReference(AspectContext info) { if (info.TargetTypeContext != this) { throw new NotSupportedException("Aspect info mismatch."); } TargetMethodContext initMethod = null; FieldAttributes fieldAttrs; string aspectPropertyName = null; if (info.AdviceClassScope == AspectScope.Instance) { fieldAttrs = FieldAttributes.Private; initMethod = InstanсeAspectsInitializer; aspectPropertyName = AspectInstancePropertyNamePrefix + info.AdviceClassType.Name; } else if (info.AdviceClassScope == AspectScope.Type) { fieldAttrs = FieldAttributes.Private | FieldAttributes.Static; initMethod = TypeAspectsInitializer; aspectPropertyName = AspectStaticPropertyNamePrefix + info.AdviceClassType.Name; } else { throw new NotSupportedException("Scope " + info.AdviceClassScope.ToString() + " is not supported (yet)."); } var existingField = TypeDefinition.Fields.FirstOrDefault(f => f.Name == aspectPropertyName && f.FieldType.IsTypeOf(info.AdviceClassType)); if (existingField != null) { return(existingField); } var field = new FieldDefinition(aspectPropertyName, fieldAttrs, TypeDefinition.Module.Import(info.AdviceClassType)); TypeDefinition.Fields.Add(field); InjectInitialization(initMethod, field, info.AdviceClassFactory); return(field); }
public static TargetMethodContext GetOrCreateContext(MethodDefinition md) { lock (Contexts) { TargetMethodContext result; if (!Contexts.TryGetValue(md, out result)) { if (md.CustomAttributes.HasAttributeOfType <AsyncStateMachineAttribute>() /* && md.ReturnType != md.Module.TypeSystem.Void*/) { result = new TargetAsyncMethodContext(md, ModuleContext.GetOrCreateContext(md.Module)); } else { result = new TargetMethodContext(md, ModuleContext.GetOrCreateContext(md.Module)); } Contexts.Add(md, result); } return(result); } }