MethodDefinition InjectInterceptedMethod(TypeDefinition targetType, MethodDefinition innerOnPropertyChanging) { var delegateHolderInjector = new DelegateHolderInjector { TargetTypeDefinition=targetType, OnPropertyChangingMethodReference = innerOnPropertyChanging, ModuleWeaver = this }; delegateHolderInjector.InjectDelegateHolder(); var method = new MethodDefinition(EventInvokerNames.First(), GetMethodAttributes(targetType), ModuleDefinition.TypeSystem.Void); var propertyName = new ParameterDefinition("propertyName", ParameterAttributes.None, ModuleDefinition.TypeSystem.String); method.Parameters.Add(propertyName); if (InterceptorType == InvokerTypes.Before) { var before = new ParameterDefinition("before", ParameterAttributes.None, ModuleDefinition.TypeSystem.Object); method.Parameters.Add(before); } var action = new VariableDefinition("firePropertyChanging", ActionTypeReference); method.Body.Variables.Add(action); var variableDefinition = new VariableDefinition("delegateHolder", delegateHolderInjector.TypeDefinition); method.Body.Variables.Add(variableDefinition); var instructions = method.Body.Instructions; var last = Instruction.Create(OpCodes.Ret); instructions.Add(Instruction.Create(OpCodes.Newobj, delegateHolderInjector.ConstructorDefinition)); instructions.Add(Instruction.Create(OpCodes.Stloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldarg_1)); instructions.Add(Instruction.Create(OpCodes.Stfld, delegateHolderInjector.PropertyName)); instructions.Add(Instruction.Create(OpCodes.Ldloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); instructions.Add(Instruction.Create(OpCodes.Stfld, delegateHolderInjector.Target)); instructions.Add(Instruction.Create(OpCodes.Ldloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldftn, delegateHolderInjector.MethodDefinition)); instructions.Add(Instruction.Create(OpCodes.Newobj, ActionConstructorReference)); instructions.Add(Instruction.Create(OpCodes.Stloc_0)); instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); instructions.Add(Instruction.Create(OpCodes.Ldloc_0)); instructions.Add(Instruction.Create(OpCodes.Ldloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldfld, delegateHolderInjector.PropertyName)); if (InterceptorType == InvokerTypes.Before) { instructions.Add(Instruction.Create(OpCodes.Ldarg_2)); instructions.Add(Instruction.Create(OpCodes.Call, InterceptMethod)); } else { instructions.Add(Instruction.Create(OpCodes.Call, InterceptMethod)); } instructions.Add(last); method.Body.InitLocals = true; targetType.Methods.Add(method); return method; }
public MethodInjector(InterceptorFinder interceptorFinder, DelegateHolderInjector delegateHolderInjector, MsCoreReferenceFinder msCoreReferenceFinder, EventInvokerNameResolver eventInvokerNameResolver) { this.interceptorFinder = interceptorFinder; this.delegateHolderInjector = delegateHolderInjector; this.msCoreReferenceFinder = msCoreReferenceFinder; this.eventInvokerNameResolver = eventInvokerNameResolver; }
MethodDefinition InjectInterceptedMethod(TypeDefinition targetType, MethodDefinition innerOnPropertyChanging) { var delegateHolderInjector = new DelegateHolderInjector { TargetTypeDefinition = targetType, OnPropertyChangingMethodReference = innerOnPropertyChanging, ModuleWeaver = this }; delegateHolderInjector.InjectDelegateHolder(); var method = new MethodDefinition(EventInvokerNames.First(), GetMethodAttributes(targetType), ModuleDefinition.TypeSystem.Void); var propertyName = new ParameterDefinition("propertyName", ParameterAttributes.None, ModuleDefinition.TypeSystem.String); method.Parameters.Add(propertyName); if (InterceptorType == InvokerTypes.Before) { var before = new ParameterDefinition("before", ParameterAttributes.None, ModuleDefinition.TypeSystem.Object); method.Parameters.Add(before); } var action = new VariableDefinition("firePropertyChanging", ActionTypeReference); method.Body.Variables.Add(action); var variableDefinition = new VariableDefinition("delegateHolder", delegateHolderInjector.TypeDefinition); method.Body.Variables.Add(variableDefinition); var instructions = method.Body.Instructions; var last = Instruction.Create(OpCodes.Ret); instructions.Add(Instruction.Create(OpCodes.Newobj, delegateHolderInjector.ConstructorDefinition)); instructions.Add(Instruction.Create(OpCodes.Stloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldarg_1)); instructions.Add(Instruction.Create(OpCodes.Stfld, delegateHolderInjector.PropertyName)); instructions.Add(Instruction.Create(OpCodes.Ldloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); instructions.Add(Instruction.Create(OpCodes.Stfld, delegateHolderInjector.Target)); instructions.Add(Instruction.Create(OpCodes.Ldloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldftn, delegateHolderInjector.MethodDefinition)); instructions.Add(Instruction.Create(OpCodes.Newobj, ActionConstructorReference)); instructions.Add(Instruction.Create(OpCodes.Stloc_0)); instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); instructions.Add(Instruction.Create(OpCodes.Ldloc_0)); instructions.Add(Instruction.Create(OpCodes.Ldloc_1)); instructions.Add(Instruction.Create(OpCodes.Ldfld, delegateHolderInjector.PropertyName)); if (InterceptorType == InvokerTypes.Before) { instructions.Add(Instruction.Create(OpCodes.Ldarg_2)); instructions.Add(Instruction.Create(OpCodes.Call, InterceptMethod)); } else { instructions.Add(Instruction.Create(OpCodes.Call, InterceptMethod)); } instructions.Add(last); method.Body.InitLocals = true; targetType.Methods.Add(method); return(method); }