private void GenerateSetMethodBody(ICommonAssembly assembly, IHasMethods viewModelBaseType, ICommonType viewModelType, PropertyGroup group, FieldReference field) { log.Info("Generate set method body..."); var property = group.Property; if (property.SetMethod == null) { log.Debug($"Create set accessor method for property '{property.Name}'"); var setMethod = new MethodDefinition($"set_{property.Name}", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, assembly.MonoCecil.MainModule.TypeSystem.Void); setMethod.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, property.MonoCecil.PropertyType)); property.MonoCecil.SetMethod = setMethod; viewModelType.MonoCecil.Methods.Add(setMethod); } var setMethodFromViewModelBaseWithGeneric = new GenericInstanceMethod(viewModelBaseType.GetMethod("Set", new[] { typeof(string).FullName, "T&", "T", typeof(bool).FullName }, true).MonoCecil); setMethodFromViewModelBaseWithGeneric.GenericArguments.Add(property.MonoCecil.PropertyType); var importedSetMethodFromViewModelBaseWithGeneric = assembly.MonoCecil.MainModule.ImportReference(setMethodFromViewModelBaseWithGeneric); var callMethodAfterSetPropertyInstructions = CreateCallMethodInstructions(group.CalledMethodAfterSetProperty).ToArray(); property.MonoCecil.SetMethod.Body.Variables.Clear(); property.MonoCecil.SetMethod.Body.Instructions.Clear(); CreateCallMethodInstructions(group.CalledMethodBeforeSetProperty).ForEach(property.MonoCecil.SetMethod.Body.Instructions.Add); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldstr, property.Name)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldflda, field)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_1)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4_0)); property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Call, importedSetMethodFromViewModelBaseWithGeneric)); var returnInstruction = Instruction.Create(OpCodes.Ret); if (group.CalledMethodAfterSuccessSetProperty != null) { var firstInstructionAfterJump = callMethodAfterSetPropertyInstructions.FirstOrDefault() ?? returnInstruction; property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Brfalse_S, firstInstructionAfterJump)); CreateCallMethodInstructions(group.CalledMethodAfterSuccessSetProperty).ForEach(property.MonoCecil.SetMethod.Body.Instructions.Add); } else { property.MonoCecil.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Pop)); } callMethodAfterSetPropertyInstructions.ForEach(property.MonoCecil.SetMethod.Body.Instructions.Add); property.MonoCecil.SetMethod.Body.Instructions.Add(returnInstruction); property.MonoCecil.SetMethod.RemoveAttributes <CompilerGeneratedAttribute>(); log.Info("Set method body was generated"); }
public static ICommonMethod GetMethod(this IHasMethods hasMethods, string methodName, IHasType[] methodParameterHasTypes, bool throwExceptionIfNotFound = false) { return(hasMethods.GetMethod(methodName, methodParameterHasTypes.Select(type => type.Type).ToArray(), throwExceptionIfNotFound)); }
public static ICommonMethod GetMethod(this IHasMethods hasMethods, string methodName, bool throwExceptionIfNotFound = false) { return(hasMethods.GetMethod(methodName, Type.EmptyTypes, throwExceptionIfNotFound)); }
public static bool TryGetMethod(this IHasMethods hasMethods, string methodName, string[] methodParameterTypeFullNames, out ICommonMethod foundCommonMethod) { return((foundCommonMethod = hasMethods.GetMethod(methodName, methodParameterTypeFullNames)) != null); }
public static bool TryGetMethod(this IHasMethods hasMethods, string methodName, out ICommonMethod foundCommonMethod) { return((foundCommonMethod = hasMethods.GetMethod(methodName)) != null); }