MethodDefinition InjectMethod(TypeDefinition targetType, string eventInvokerName, FieldReference propertyChangedField)
{
var method = new MethodDefinition(eventInvokerName, GetMethodAttributes(targetType), msCoreReferenceFinder.VoidTypeReference);
method.Parameters.Add(new ParameterDefinition("propertyName", ParameterAttributes.None, msCoreReferenceFinder.StringTypeReference));
var handlerVariable = new VariableDefinition(msCoreReferenceFinder.PropChangedHandlerReference);
method.Body.Variables.Add(handlerVariable);
var boolVariable = new VariableDefinition(msCoreReferenceFinder.BoolTypeReference);
method.Body.Variables.Add(boolVariable);
var instructions = method.Body.Instructions;
var last = Instruction.Create(OpCodes.Ret);
instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
instructions.Add(Instruction.Create(OpCodes.Ldfld, propertyChangedField));
instructions.Add(Instruction.Create(OpCodes.Stloc_0));
instructions.Add(Instruction.Create(OpCodes.Ldloc_0));
instructions.Add(Instruction.Create(OpCodes.Ldnull));
instructions.Add(Instruction.Create(OpCodes.Ceq));
instructions.Add(Instruction.Create(OpCodes.Stloc_1));
instructions.Add(Instruction.Create(OpCodes.Ldloc_1));
instructions.Add(Instruction.Create(OpCodes.Brtrue_S, last));
instructions.Add(Instruction.Create(OpCodes.Ldloc_0));
instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
instructions.Add(Instruction.Create(OpCodes.Ldarg_1));
instructions.Add(Instruction.Create(OpCodes.Newobj, msCoreReferenceFinder.ComponentModelPropertyChangedEventConstructorReference));
instructions.Add(Instruction.Create(OpCodes.Callvirt, msCoreReferenceFinder.ComponentModelPropertyChangedEventHandlerInvokeReference));
instructions.Add(last);
method.Body.InitLocals = true;
targetType.Methods.Add(method);
return method;
}