private void ProcessProperty(CatelType catelType, CatelTypeProperty modelProperty, CustomAttribute exposeAttribute) { var modelName = modelProperty.Name; var viewModelPropertyName = (string)exposeAttribute.ConstructorArguments[0].Value; var modelPropertyName = viewModelPropertyName; if (exposeAttribute.ConstructorArguments.Count > 1) { modelPropertyName = (string)(exposeAttribute.ConstructorArguments[1].Value ?? viewModelPropertyName); } var isReadOnly = false; var isReadOnlyProperty = (from property in exposeAttribute.Properties where string.Equals(property.Name, "IsReadOnly") select property).FirstOrDefault(); if (isReadOnlyProperty.Argument.Value != null) { isReadOnly = (bool)isReadOnlyProperty.Argument.Value; } // Check property definition on model var modelType = modelProperty.PropertyDefinition.PropertyType; var modelPropertyToMap = modelType.GetProperty(modelPropertyName); if (modelPropertyToMap is null) { FodyEnvironment.WriteError($"Exposed property '{modelPropertyName}' does not exist on model '{modelType.FullName}', make sure to set the right mapping"); return; } var modelPropertyType = modelType.ResolveGenericPropertyType(modelPropertyToMap); var viewModelPropertyDefinition = new PropertyDefinition(viewModelPropertyName, PropertyAttributes.None, FodyEnvironment.ModuleDefinition.ImportReference(modelPropertyType)); viewModelPropertyDefinition.DeclaringType = catelType.TypeDefinition; catelType.TypeDefinition.Properties.Add(viewModelPropertyDefinition); viewModelPropertyDefinition.MarkAsCompilerGenerated(_msCoreReferenceFinder); var catelTypeProperty = new CatelTypeProperty(catelType.TypeDefinition, viewModelPropertyDefinition); catelTypeProperty.IsReadOnly = isReadOnly; var catelPropertyWeaver = new ModelBasePropertyWeaver(catelType, catelTypeProperty, _configuration, _moduleWeaver, _msCoreReferenceFinder); catelPropertyWeaver.Execute(true); var stringType = _msCoreReferenceFinder.GetCoreTypeReference("String"); var stringTypeDefinition = catelType.TypeDefinition.Module.ImportReference(stringType); var attributeConstructor = catelType.TypeDefinition.Module.ImportReference(_viewModelToModelAttributeTypeDefinition.Constructor(false)); var viewModelToModelAttribute = new CustomAttribute(attributeConstructor); viewModelToModelAttribute.ConstructorArguments.Add(new CustomAttributeArgument(stringTypeDefinition, modelName)); viewModelToModelAttribute.ConstructorArguments.Add(new CustomAttributeArgument(stringTypeDefinition, modelPropertyName)); viewModelPropertyDefinition.CustomAttributes.Add(viewModelToModelAttribute); }
private void Process(List <CatelType> catelTypes) { foreach (var catelType in catelTypes) { FodyEnvironment.WriteDebug($"\tExecuting '{GetType().Name}' for '{catelType.TypeDefinition.FullName}'"); foreach (var propertyData in catelType.Properties) { var body = propertyData.PropertyDefinition.SetMethod.Body; body.SimplifyMacros(); switch (catelType.Type) { case CatelTypeType.ViewModel: case CatelTypeType.Model: var modelBasePropertyWeaver = new ModelBasePropertyWeaver(catelType, propertyData, _configuration, _moduleWeaver, _msCoreReferenceFinder); modelBasePropertyWeaver.Execute(); break; case CatelTypeType.ObservableObject: var observableObjectPropertyWeaver = new ObservableObjectPropertyWeaver(catelType, propertyData, _moduleWeaver, _msCoreReferenceFinder); observableObjectPropertyWeaver.Execute(); break; default: break; } body.InitLocals = true; body.OptimizeMacros(); } if (_configuration.WeaveCalculatedProperties) { var onPropertyChangedWeaver = new OnPropertyChangedWeaver(catelType, _msCoreReferenceFinder); onPropertyChangedWeaver.Execute(); } // Note: for now this is disabled. In advanced scenarios (see unit test for ReplacesRaisePropertyChanged_Advanced), it somehow does // not correctly replace the "leave_s" operand. The quick watch shows that the method is correctly updated, but the IL *and* the unit test // both show incorrect execution //var raisePropertyChangedWeaver = new RaisePropertyChangedWeaver(catelType, _msCoreReferenceFinder); //raisePropertyChangedWeaver.Execute(); } }