private void GenerateGetMethodBody(ICommonType viewModelType, PropertyGroup group, FieldReference field)
        {
            log.Info("Generate get method body...");

            var property = group.Property;

            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.MonoCecil.PropertyType);

                property.MonoCecil.GetMethod = getMethod;
                viewModelType.MonoCecil.Methods.Add(getMethod);
            }

            property.MonoCecil.GetMethod.Body.Variables.Clear();
            property.MonoCecil.GetMethod.Body.Instructions.Clear();
            CreateCallMethodInstructions(group.CalledMethodBeforeGetProperty).ForEach(property.MonoCecil.GetMethod.Body.Instructions.Add);
            property.MonoCecil.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            property.MonoCecil.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldfld, field));
            property.MonoCecil.GetMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

            property.MonoCecil.GetMethod.RemoveAttributes <CompilerGeneratedAttribute>();

            log.Info("Get method body was generated");
        }
        private void Patch(ICommonType type)
        {
            if (type != null)
            {
                assembly.AddCommonType(type);
            }

            new MonoCecilSelectedTypesPatcher(new ApplicationPatcherSelfConfiguration {
                MonoCecilSelectedPatchingTypeFullNames = new[] { type?.Name, "AnyName" }.Where(typeName => !typeName.IsNullOrEmpty()).ToArray()
            }).Patch(assembly.CommonAssembly);
        }
        public DependencyGroup[] GetGroups(ICommonAssembly assembly, ICommonType frameworkElementType, FrameworkElementPatchingType patchingType)
        {
            var dependencyPropertyType = assembly.GetCommonType(KnownTypeNames.DependencyProperty, true);

            CheckFrameworkElement(frameworkElementType, dependencyPropertyType);

            var patchingProperties = GetPatchingProperties(frameworkElementType, patchingType);

            CheckPatchingPropertyNames(patchingProperties);

            var patchingDependencyGroups = GetPatchingDependencyGroups(patchingProperties, frameworkElementType);

            CheckPatchingPropertyGroups(patchingDependencyGroups, dependencyPropertyType);

            return(patchingDependencyGroups.Select(group => new DependencyGroup(group.Fields.SingleOrDefault(), group.Property)).ToArray());
        }
        public override PatchResult Patch(ICommonAssembly assembly, ICommonType viewModelBaseType, ICommonType viewModelType, ViewModelPatchingType patchingType)
        {
            log.Info("Patching property groups...");

            var propertyGroups = propertyGrouperService.GetGroups(assembly, viewModelType, patchingType);

            if (!propertyGroups.Any())
            {
                log.Info("Not found property groups");
                return(PatchResult.Continue);
            }

            log.Debug("Property groups found:", propertyGroups.Select(group => $"Property: '{group.Property.Name}', field: '{group.Field?.Name}'"));

            foreach (var group in propertyGroups)
            {
                log.Info($"Patch group: property: '{group.Property.Name}', field: '{group.Field?.Name}'...");
                PatchGroup(assembly, viewModelBaseType, viewModelType, group);
                log.Info("Group was patched");
            }

            log.Info("Property groups was patched");
            return(PatchResult.Continue);
        }