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);
 }