private PropertyDefinition CreateProperty(ICommonAssembly assembly, ICommonType viewModelType, string executeMethodName) { var propertyName = nameRulesService.ConvertName(executeMethodName, UseNameRulesFor.CommandExecuteMethod, UseNameRulesFor.CommandProperty); log.Debug($"Create property with name '{propertyName}'"); var property = new PropertyDefinition(propertyName, PropertyAttributes.None, assembly.MonoCecil.MainModule.ImportReference(commandType.GetValue(assembly).MonoCecil)); viewModelType.MonoCecil.Properties.Add(property); return(property); }
private void GenerateGetMethodBody(ICommonAssembly assembly, ICommonType viewModelType, ICommonMethod executeMethod, ICommonMethod canExecuteMethod, PropertyDefinition property, FieldReference field) { log.Info("Generate get method body..."); if (property.GetMethod == null) { log.Debug($"Create get accessor method for property '{property.Name}'"); var getMethod = new MethodDefinition($"get_{property.Name}", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, property.PropertyType); property.GetMethod = getMethod; viewModelType.MonoCecil.Methods.Add(getMethod); } var returnInstruction = Instruction.Create(OpCodes.Ret); property.GetMethod.Body.Variables.Clear(); property.GetMethod.Body.InitLocals = true; property.GetMethod.Body.Variables.Add(new VariableDefinition(assembly.MonoCecil.MainModule.ImportReference(commandType.GetValue(assembly).MonoCecil))); property.GetMethod.Body.Instructions.Clear(); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldfld, field)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Dup)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Brtrue_S, returnInstruction)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Pop)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldftn, executeMethod.MonoCecil)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Newobj, actionConstructor.GetValue(assembly))); if (canExecuteMethod == null) { property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4_0)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Newobj, relayCommandConstructor.GetValue(assembly))); } else { property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldftn, canExecuteMethod.MonoCecil)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Newobj, funcBoolConstructor.GetValue(assembly))); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4_0)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Newobj, relayCommandConstructorWithCanExecuteMethod.GetValue(assembly))); } property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Dup)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Stloc_0)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Stfld, field)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldloc_0)); property.GetMethod.Body.Instructions.Add(returnInstruction); property.GetMethod.RemoveAttributes <CompilerGeneratedAttribute>(); log.Info("Get method body was generated"); }
private FieldDefinition CreateField(ICommonAssembly assembly, ICommonType frameworkElementType, ICommonProperty property) { var fieldName = nameRulesService.ConvertName(property.Name, UseNameRulesFor.DependencyProperty, UseNameRulesFor.DependencyField); log.Debug($"Create field with name '{fieldName}'"); var field = new FieldDefinition(fieldName, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly, assembly.MonoCecil.MainModule.ImportReference(dependencyPropertyType.GetValue(assembly).MonoCecil)); frameworkElementType.MonoCecil.Fields.Add(field); InitializeInStaticConstructor(assembly, frameworkElementType, property, field); return(field); }
private void GenerateSetMethodBody(ICommonAssembly assembly, ICommonType frameworkElementType, PropertyDefinition property, FieldReference field) { log.Info("Generate set method body..."); 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.PropertyType)); property.SetMethod = setMethod; frameworkElementType.MonoCecil.Methods.Add(setMethod); } property.GetMethod.Body.Variables.Clear(); property.SetMethod.Body.Instructions.Clear(); property.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, field)); property.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_1)); if (property.PropertyType.IsValueType) { property.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Box, property.PropertyType)); } property.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Call, setValueMethod.GetValue(assembly))); property.SetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); property.SetMethod.RemoveAttributes <CompilerGeneratedAttribute>(); log.Info("Set method body was generated"); }
private void GenerateGetMethodBody(ICommonAssembly assembly, ICommonType frameworkElementType, PropertyDefinition property, FieldReference field) { log.Info("Generate get method body..."); if (property.GetMethod == null) { log.Debug($"Create get accessor method for property '{property.Name}'"); var getMethod = new MethodDefinition($"get_{property.Name}", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, property.PropertyType); property.GetMethod = getMethod; frameworkElementType.MonoCecil.Methods.Add(getMethod); } property.GetMethod.Body.Variables.Clear(); property.GetMethod.Body.Instructions.Clear(); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld, field)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Call, getValueMethod.GetValue(assembly))); property.GetMethod.Body.Instructions.Add(Instruction.Create(property.PropertyType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, property.PropertyType)); property.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); property.GetMethod.RemoveAttributes <CompilerGeneratedAttribute>(); log.Info("Get method body was generated"); }
private void InitializeInStaticConstructor(ICommonAssembly assembly, ICommonType frameworkElementType, ICommonProperty property, FieldReference field) { var staticConstructor = frameworkElementType.MonoCecil.GetStaticConstructor(); if (staticConstructor == null) { staticConstructor = new MethodDefinition(".cctor", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Static, assembly.MonoCecil.MainModule.TypeSystem.Void); staticConstructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); frameworkElementType.MonoCecil.Methods.Add(staticConstructor); } staticConstructor.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldstr, property.Name)); staticConstructor.Body.Instructions.Insert(1, Instruction.Create(OpCodes.Ldtoken, property.MonoCecil.PropertyType)); staticConstructor.Body.Instructions.Insert(2, Instruction.Create(OpCodes.Call, getTypeFromHandleMethod.GetValue(assembly))); staticConstructor.Body.Instructions.Insert(3, Instruction.Create(OpCodes.Ldtoken, frameworkElementType.MonoCecil)); staticConstructor.Body.Instructions.Insert(4, Instruction.Create(OpCodes.Call, getTypeFromHandleMethod.GetValue(assembly))); staticConstructor.Body.Instructions.Insert(5, Instruction.Create(OpCodes.Call, registerMethod.GetValue(assembly))); staticConstructor.Body.Instructions.Insert(6, Instruction.Create(OpCodes.Stsfld, field)); }