private void PatchProprty(MonoCecilAssembly monoCecilAssembly, CommonType viewModelBase, CommonType viewModel, CommonProperty property) { CheckProperty(property); var propertyName = property.Name; log.Debug($"Property name: {propertyName}"); var backgroundFieldName = $"{char.ToLower(propertyName.First())}{propertyName.Substring(1)}"; log.Debug($"Background field name: {backgroundFieldName}"); var backgroundField = viewModel.Fields.FirstOrDefault(field => field.Name == backgroundFieldName)?.MonoCecilField; if (backgroundField == null) { backgroundField = monoCecilFactory.CreateField(backgroundFieldName, FieldAttributes.Private, property.MonoCecilProperty.PropertyType); viewModel.MonoCecilType.AddField(backgroundField); log.Debug("Background field was created"); } else { log.Debug("Background field was connected"); } GenerateGetMethodBody(property.MonoCecilProperty, backgroundField); GenerateSetMethodBody(monoCecilAssembly, viewModelBase, property.MonoCecilProperty, propertyName, backgroundField); }
private void GenerateSetMethodBody(MonoCecilAssembly monoCecilAssembly, CommonType viewModelBase, MonoCecilProperty property, string propertyName, MonoCecilField backgroundField) { log.Info("Generate method reference on Set method in ViewModelBase..."); var propertySetMethod = property.SetMethod; if (propertySetMethod == null) { const string errorMessage = "Patching property must have set method accessor"; log.Error(errorMessage); throw new PropertyPatchingException(errorMessage, property.FullName); } var setMethodFromViewModelBase = monoCecilFactory.CreateGenericInstanceMethod(GetSetMethodFromViewModelBase(viewModelBase.MonoCecilType)); setMethodFromViewModelBase.AddGenericArgument(property.PropertyType); var setMethodInViewModelBaseWithGenericParameter = monoCecilAssembly.MainModule.Import(setMethodFromViewModelBase); log.Info("Generate set method body..."); var setMethodBodyInstructions = propertySetMethod.Body.Instructions; setMethodBodyInstructions.Clear(); setMethodBodyInstructions.Add(monoCecilFactory.CreateInstruction(OpCodes.Ldarg_0)); setMethodBodyInstructions.Add(monoCecilFactory.CreateInstruction(OpCodes.Ldstr, propertyName)); setMethodBodyInstructions.Add(monoCecilFactory.CreateInstruction(OpCodes.Ldarg_0)); setMethodBodyInstructions.Add(monoCecilFactory.CreateInstruction(OpCodes.Ldflda, backgroundField)); setMethodBodyInstructions.Add(monoCecilFactory.CreateInstruction(OpCodes.Ldarg_1)); setMethodBodyInstructions.Add(monoCecilFactory.CreateInstruction(OpCodes.Ldc_I4_0)); setMethodBodyInstructions.Add(monoCecilFactory.CreateInstruction(OpCodes.Call, setMethodInViewModelBaseWithGenericParameter)); setMethodBodyInstructions.Add(monoCecilFactory.CreateInstruction(OpCodes.Pop)); setMethodBodyInstructions.Add(monoCecilFactory.CreateInstruction(OpCodes.Ret)); propertySetMethod.RemoveAttribute(typeof(CompilerGeneratedAttribute)); log.Info("Set method body was generated"); }
public void Patch(MonoCecilAssembly monoCecilAssembly, CommonTypeContainer commonTypeContainer) { log.Info("Patching view models..."); var viewModels = commonTypeContainer.GetInheritanceCommonTypes(typeof(ViewModelBase)).WhereFrom(monoCecilAssembly.MainModule).ToArray(); if (!viewModels.Any()) { log.Info("Not found view models"); return; } var viewModelBase = commonTypeContainer.GetCommonType(typeof(ViewModelBase)).Load(); log.Debug("View models found:", viewModels.Select(viewModel => viewModel.FullName)); foreach (var viewModel in viewModels) { log.Info($"Patching {viewModel.FullName}..."); viewModel.Load(); var patchingViewModelAttribute = viewModel.GetReflectionAttribute <PatchingViewModelAttribute>(); var viewModelPatchingType = patchingViewModelAttribute?.ViewModelPatchingType ?? ViewModelPatchingType.All; log.Info($"View model patching type: {viewModelPatchingType}"); viewModelPartPatchers.ForEach(viewModelPartPatcher => viewModelPartPatcher.Patch(monoCecilAssembly, viewModelBase, viewModel, viewModelPatchingType)); log.Info($"{viewModel.FullName} was patched"); } log.Info("View models was patched"); }
private static IEnumerable <MonoCecilType> GetAllTypes(MonoCecilAssembly monoCecilAssembly) { var types = new List <MonoCecilType>(); monoCecilAssembly.MainModule.Types.ForEach(type => AddType(types, type)); return(types); }
public void Patch(MonoCecilAssembly monoCecilAssembly, CommonType viewModelBase, CommonType viewModel, ViewModelPatchingType viewModelPatchingType) { log.Info($"Patching {viewModel.FullName} commands..."); var commandMethods = GetCommonCommandMethods(viewModel, viewModelPatchingType); var commandProperties = GetCommonCommandProperties(viewModel, viewModelPatchingType); var commandsMembers = JoinMembers(commandMethods, commandProperties); }
public void Patch(MonoCecilAssembly monoCecilAssembly, CommonType viewModelBase, CommonType viewModel, ViewModelPatchingType viewModelPatchingType) { log.Info($"Patching {viewModel.FullName} properties..."); var properties = GetCommonProperties(viewModel, viewModelPatchingType); if (!properties.Any()) { log.Info("Not found properties"); return; } log.Debug("Properties found:", properties.Select(property => property.FullName)); foreach (var property in properties) { log.Info($"Patching {property.FullName}..."); PatchProprty(monoCecilAssembly, viewModelBase, viewModel, property); log.Info($"{property.FullName} was patched"); } log.Info($"Properties {viewModel.FullName} was patched"); }
public virtual CommonTypeContainer Create(ReflectionAssembly reflectionAssembly, MonoCecilAssembly monoCecilAssembly) { var allTypes = GetAllTypes(monoCecilAssembly); return(CreateCommonAssemblyContainer(reflectionAssembly, allTypes)); }
public virtual void Save(MonoCecilAssembly monoCecilAssembly, string assemblyPath) { monoCecilAssembly.Instance.Write(assemblyPath, new WriterParameters { WriteSymbols = true }); }