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");
        }
Exemplo n.º 3
0
        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");
        }
Exemplo n.º 4
0
        private static IEnumerable <MonoCecilType> GetAllTypes(MonoCecilAssembly monoCecilAssembly)
        {
            var types = new List <MonoCecilType>();

            monoCecilAssembly.MainModule.Types.ForEach(type => AddType(types, type));

            return(types);
        }
Exemplo n.º 5
0
        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");
        }
Exemplo n.º 7
0
        public virtual CommonTypeContainer Create(ReflectionAssembly reflectionAssembly, MonoCecilAssembly monoCecilAssembly)
        {
            var allTypes = GetAllTypes(monoCecilAssembly);

            return(CreateCommonAssemblyContainer(reflectionAssembly, allTypes));
        }
Exemplo n.º 8
0
 public virtual void Save(MonoCecilAssembly monoCecilAssembly, string assemblyPath)
 {
     monoCecilAssembly.Instance.Write(assemblyPath, new WriterParameters {
         WriteSymbols = true
     });
 }