Repository: kswoll/ReactiveUI.Fody Branch: rxui7beta Commit: 6c002e709f46 Files: 58 Total size: 119.0 KB Directory structure: gitextract_4be4dugx/ ├── .gitignore ├── .nuget/ │ └── packages.config ├── LICENSE ├── Nuget/ │ └── ReactiveUIFody.nuspec ├── ReactiveUI.Fody/ │ ├── CecilExtensions.cs │ ├── ModuleWeaver.cs │ ├── ObservableAsPropertyWeaver.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── ReactiveDependencyPropertyWeaver.cs │ ├── ReactiveUI.Fody.csproj │ ├── ReactiveUIPropertyWeaver.cs │ └── packages.config ├── ReactiveUI.Fody.Helpers/ │ ├── LogPropertyOnErrorException.cs │ ├── LogPropertyOnErrorObservable.cs │ ├── ObservableAsPropertyAttribute.cs │ ├── ObservableAsPropertyExtensions.cs │ ├── ReactiveAttribute.cs │ ├── ReactiveDependencyAttribute.cs │ ├── ReactivePropertyExtensions.cs │ ├── ReactiveUI.Fody.Helpers.projitems │ ├── ReactiveUI.Fody.Helpers.shproj │ └── Settings/ │ └── GlobalSettings.cs ├── ReactiveUI.Fody.Helpers.Android/ │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── ReactiveUI.Fody.Helpers.Android.csproj │ ├── Resources/ │ │ ├── AboutResources.txt │ │ ├── Resource.Designer.cs │ │ └── Values/ │ │ └── Strings.xml │ └── packages.config ├── ReactiveUI.Fody.Helpers.Ios/ │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── ReactiveUI.Fody.Helpers.Ios.csproj │ └── packages.config ├── ReactiveUI.Fody.Helpers.Net45/ │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── ReactiveUI.Fody.Helpers.Net45.csproj │ └── packages.config ├── ReactiveUI.Fody.Helpers.Pcl/ │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── ReactiveUI.Fody.Helpers.Pcl.csproj │ └── packages.config ├── ReactiveUI.Fody.Tests/ │ ├── FodyWeavers.xml │ ├── Issues/ │ │ ├── Issue10Tests.cs │ │ ├── Issue11Tests.cs │ │ ├── Issue13Tests.cs │ │ ├── Issue31Tests.cs │ │ ├── Issue41Tests.cs │ │ └── Issue47Tests.cs │ ├── ObservableAsPropertyTests.cs │ ├── Properties/ │ │ └── AssemblyInfo.cs │ ├── ReactiveDependencyTests.cs │ ├── ReactiveUI.Fody.Tests.csproj │ └── packages.config ├── ReactiveUIFody.sln ├── ReactiveUIFody.sln.DotSettings ├── ReactiveUIFodyAll.sln ├── Readme.md ├── Weavers/ │ └── bin/ │ └── _._ ├── artifacts/ │ ├── MonoAndroid/ │ │ ├── ReactiveUI.Fody.Helpers.dll.mdb │ │ └── ReactiveUI.Fody.Helpers.pdb │ └── Xamarin.iOS10/ │ └── ReactiveUI.Fody.Helpers.pdb └── makepackage.bat ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ packages/ *.nupkg *.suo *.userprefs *.user ReactiveUI.Fody/obj/ ReactiveUI.Fody/bin/ ReactiveUI.Fody.Helpers.Net45/obj/ ReactiveUI.Fody.Helpers.Net45/bin/ ReactiveUI.Fody.Helpers.Ios/bin/ ReactiveUI.Fody.Helpers.Ios/obj/ ReactiveUI.Fody.Helpers.Android/bin/ ReactiveUI.Fody.Helpers.Android/obj/ Nuget/ReactiveUI.Fody.1.0.26/ ReactiveUI.Fody.1.0.26/ ReactiveUI.Fody.Helpers.Pcl/obj/ ReactiveUI.Fody.Helpers.Pcl/bin/ ReactiveUI.Fody.Tests/bin/ ReactiveUI.Fody.Tests/obj/ Weavers/bin/Weavers.dll Weavers/bin/Weavers.pdb _ReSharper.Caches ================================================ FILE: .nuget/packages.config ================================================  ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2014 Kirk Woll Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Nuget/ReactiveUIFody.nuspec ================================================ ReactiveUI.Fody 2.0.0 kirk kirk https://github.com/kswoll/ReactiveUI.Fody http://www.opensource.org/licenses/mit-license.php Fix some other bugs around properties in generic types. false Fody extension to generate RaisePropertyChange notifications for properties and ObservableAsPropertyHelper properties. Copyright 2015 reactiveui fody ================================================ FILE: ReactiveUI.Fody/CecilExtensions.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; namespace ReactiveUI.Fody { public static class CecilExtensions { public static void Emit(this MethodBody body, Action il) { il(body.GetILProcessor()); } public static GenericInstanceMethod MakeGenericMethod(this MethodReference method, params TypeReference[] genericArguments) { var result = new GenericInstanceMethod(method); foreach (var argument in genericArguments) result.GenericArguments.Add(argument); return result; } public static bool IsAssignableFrom(this TypeReference baseType, TypeReference type, Action logger = null) { return baseType.Resolve().IsAssignableFrom(type.Resolve(), logger); } public static bool IsAssignableFrom(this TypeDefinition baseType, TypeDefinition type, Action logger = null) { logger = logger ?? (x => {}); Queue queue = new Queue(); queue.Enqueue(type); while (queue.Any()) { var current = queue.Dequeue(); logger(current.FullName); if (baseType.FullName == current.FullName) return true; if (current.BaseType != null) queue.Enqueue(current.BaseType.Resolve()); foreach (var @interface in current.Interfaces) { queue.Enqueue(@interface.InterfaceType.Resolve()); } } return false; } public static bool IsDefined(this IMemberDefinition member, TypeReference attributeType) { return member.HasCustomAttributes && member.CustomAttributes.Any(x => x.AttributeType.FullName == attributeType.FullName); } public static MethodReference Bind(this MethodReference method, GenericInstanceType genericType) { var reference = new MethodReference(method.Name, method.ReturnType, genericType); reference.HasThis = method.HasThis; reference.ExplicitThis = method.ExplicitThis; reference.CallingConvention = method.CallingConvention; foreach (var parameter in method.Parameters) reference.Parameters.Add(new ParameterDefinition(parameter.ParameterType)); return reference; } /* public static MethodReference BindDefinition(this MethodReference method, TypeReference genericTypeDefinition) { if (!genericTypeDefinition.HasGenericParameters) return method; var genericDeclaration = new GenericInstanceType(genericTypeDefinition); foreach (var parameter in genericTypeDefinition.GenericParameters) { genericDeclaration.GenericArguments.Add(parameter); } var reference = new MethodReference(method.Name, method.ReturnType, genericDeclaration); reference.HasThis = method.HasThis; reference.ExplicitThis = method.ExplicitThis; reference.CallingConvention = method.CallingConvention; foreach (var parameter in method.Parameters) reference.Parameters.Add(new ParameterDefinition(parameter.ParameterType)); return reference; } */ public static FieldReference BindDefinition(this FieldReference field, TypeReference genericTypeDefinition) { if (!genericTypeDefinition.HasGenericParameters) return field; var genericDeclaration = new GenericInstanceType(genericTypeDefinition); foreach (var parameter in genericTypeDefinition.GenericParameters) { genericDeclaration.GenericArguments.Add(parameter); } var reference = new FieldReference(field.Name, field.FieldType, genericDeclaration); return reference; } public static AssemblyNameReference FindAssembly(this ModuleDefinition currentModule, string assemblyName) { return currentModule.AssemblyReferences.SingleOrDefault(x => x.Name == assemblyName); } public static TypeReference FindType(this ModuleDefinition currentModule, string @namespace, string typeName, IMetadataScope scope = null, params string[] typeParameters) { var result = new TypeReference(@namespace, typeName, currentModule, scope); foreach (var typeParameter in typeParameters) { result.GenericParameters.Add(new GenericParameter(typeParameter, result)); } return result; } public static bool CompareTo(this TypeReference type, TypeReference compareTo) { return type.FullName == compareTo.FullName; } public static IEnumerable GetMethodDependencies(this MethodDefinition method) { if (!method.IsGetter) return Enumerable.Empty(); return method.Body.Instructions.Where(i => { var operand = i.Operand as MethodDefinition; return i.OpCode == OpCodes.Call && (operand?.IsGetter ?? false); }) .SelectMany(instruction => { var methodDefinition = (MethodDefinition) instruction.Operand; return methodDefinition.GetMethodDependencies().Concat(new[] { methodDefinition }); }); } public static bool TryGetMethodDependencies(this MethodDefinition method, out MethodDefinition[] getMethods) { getMethods = method.GetMethodDependencies() .Distinct() .ToArray(); return getMethods.Any(); } /* public static IEnumerable GetAllTypes(this ModuleDefinition module) { var stack = new Stack(); foreach (var type in module.Types) { stack.Push(type); } while (stack.Any()) { var current = stack.Pop(); yield return current; foreach (var nestedType in current.NestedTypes) { stack.Push(nestedType); } } } */ } } ================================================ FILE: ReactiveUI.Fody/ModuleWeaver.cs ================================================ using System; using Mono.Cecil; namespace ReactiveUI.Fody { public class ModuleWeaver { public ModuleDefinition ModuleDefinition { get; set; } // Will log an MessageImportance.High message to MSBuild. public Action LogInfo { get; set; } // Will log an error message to MSBuild. OPTIONAL public Action LogError { get; set; } public void Execute() { var propertyWeaver = new ReactiveUIPropertyWeaver { ModuleDefinition = ModuleDefinition, LogInfo = LogInfo, LogError = LogError }; propertyWeaver.Execute(); var observableAsPropertyWeaver = new ObservableAsPropertyWeaver { ModuleDefinition = ModuleDefinition, LogInfo = LogInfo }; observableAsPropertyWeaver.Execute(); var reactiveDependencyWeaver = new ReactiveDependencyPropertyWeaver { ModuleDefinition = ModuleDefinition, LogInfo = LogInfo, LogError = LogError }; reactiveDependencyWeaver.Execute(); } } } ================================================ FILE: ReactiveUI.Fody/ObservableAsPropertyWeaver.cs ================================================ using System; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; namespace ReactiveUI.Fody { public class ObservableAsPropertyWeaver { public ModuleDefinition ModuleDefinition { get; set; } // Will log an MessageImportance.High message to MSBuild. OPTIONAL public Action LogInfo { get; set; } public void Execute() { var reactiveUI = ModuleDefinition.AssemblyReferences.Where(x => x.Name == "ReactiveUI").OrderByDescending(x => x.Version).FirstOrDefault(); if (reactiveUI == null) { LogInfo("Could not find assembly: ReactiveUI (" + string.Join(", ", ModuleDefinition.AssemblyReferences.Select(x => x.Name)) + ")"); return; } LogInfo($"{reactiveUI.Name} {reactiveUI.Version}"); var helpers = ModuleDefinition.AssemblyReferences.Where(x => x.Name == "ReactiveUI.Fody.Helpers").OrderByDescending(x => x.Version).FirstOrDefault(); if (helpers == null) { LogInfo("Could not find assembly: ReactiveUI.Fody.Helpers (" + string.Join(", ", ModuleDefinition.AssemblyReferences.Select(x => x.Name)) + ")"); return; } LogInfo($"{helpers.Name} {helpers.Version}"); var reactiveObject = ModuleDefinition.FindType("ReactiveUI", "ReactiveObject", reactiveUI); // The types we will scan are subclasses of ReactiveObject var targetTypes = ModuleDefinition.GetAllTypes().Where(x => x.BaseType != null && reactiveObject.IsAssignableFrom(x.BaseType)); var observableAsPropertyHelper = ModuleDefinition.FindType("ReactiveUI", "ObservableAsPropertyHelper`1", reactiveUI, "T"); var observableAsPropertyAttribute = ModuleDefinition.FindType("ReactiveUI.Fody.Helpers", "ObservableAsPropertyAttribute", helpers); var observableAsPropertyHelperGetValue = ModuleDefinition.ImportReference(observableAsPropertyHelper.Resolve().Properties.Single(x => x.Name == "Value").GetMethod); var exceptionType = ModuleDefinition.ImportReference(typeof(Exception)); var exceptionConstructor = ModuleDefinition.ImportReference(exceptionType.Resolve().GetConstructors().Single(x => x.Parameters.Count == 1)); foreach (var targetType in targetTypes) { foreach (var property in targetType.Properties.Where(x => x.IsDefined(observableAsPropertyAttribute) || (x.GetMethod?.IsDefined(observableAsPropertyAttribute) ?? false)).ToArray()) { var genericObservableAsPropertyHelper = observableAsPropertyHelper.MakeGenericInstanceType(property.PropertyType); var genericObservableAsPropertyHelperGetValue = observableAsPropertyHelperGetValue.Bind(genericObservableAsPropertyHelper); ModuleDefinition.ImportReference(genericObservableAsPropertyHelperGetValue); // Declare a field to store the property value var field = new FieldDefinition("$" + property.Name, FieldAttributes.Private, genericObservableAsPropertyHelper); targetType.Fields.Add(field); // It's an auto-property, so remove the generated field if (property.SetMethod != null && property.SetMethod.HasBody) { // Remove old field (the generated backing field for the auto property) var oldField = (FieldReference)property.GetMethod.Body.Instructions.Where(x => x.Operand is FieldReference).Single().Operand; var oldFieldDefinition = oldField.Resolve(); targetType.Fields.Remove(oldFieldDefinition); // Re-implement setter to throw an exception property.SetMethod.Body = new MethodBody(property.SetMethod); property.SetMethod.Body.Emit(il => { il.Emit(OpCodes.Ldstr, "Never call the setter of an ObservabeAsPropertyHelper property."); il.Emit(OpCodes.Newobj, exceptionConstructor); il.Emit(OpCodes.Throw); il.Emit(OpCodes.Ret); }); } property.GetMethod.Body = new MethodBody(property.GetMethod); property.GetMethod.Body.Emit(il => { var isValid = il.Create(OpCodes.Nop); il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldfld, field.BindDefinition(targetType)); // pop -> this.$PropertyName il.Emit(OpCodes.Dup); // Put an extra copy of this.$PropertyName onto the stack il.Emit(OpCodes.Brtrue, isValid); // If the helper is null, return the default value for the property il.Emit(OpCodes.Pop); // Drop this.$PropertyName EmitDefaultValue(property.GetMethod.Body, il, property.PropertyType); // Put the default value onto the stack il.Emit(OpCodes.Ret); // Return that default value il.Append(isValid); // Add a marker for if the helper is not null il.Emit(OpCodes.Callvirt, genericObservableAsPropertyHelperGetValue); // pop -> this.$PropertyName.Value il.Emit(OpCodes.Ret); // Return the value that is on the stack }); } } } public void EmitDefaultValue(MethodBody methodBody, ILProcessor il, TypeReference type) { if (type.CompareTo(ModuleDefinition.TypeSystem.Boolean) || type.CompareTo(ModuleDefinition.TypeSystem.Byte) || type.CompareTo(ModuleDefinition.TypeSystem.Int16) || type.CompareTo(ModuleDefinition.TypeSystem.Int32)) { il.Emit(OpCodes.Ldc_I4_0); } else if (type.CompareTo(ModuleDefinition.TypeSystem.Single)) { il.Emit(OpCodes.Ldc_R4, (float)0); } else if (type.CompareTo(ModuleDefinition.TypeSystem.Int64)) { il.Emit(OpCodes.Ldc_I8, (long)0); } else if (type.CompareTo(ModuleDefinition.TypeSystem.Double)) { il.Emit(OpCodes.Ldc_R8, (double)0); } else if (type.IsGenericParameter || type.IsValueType) { methodBody.InitLocals = true; var local = new VariableDefinition(type); il.Body.Variables.Add(local); il.Emit(OpCodes.Ldloca_S, local); il.Emit(OpCodes.Initobj, type); il.Emit(OpCodes.Ldloc, local); } else { il.Emit(OpCodes.Ldnull); } } } } ================================================ FILE: ReactiveUI.Fody/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("ReactiveUI.Fody")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ReactiveUI.Fody")] [assembly: AssemblyCopyright("Copyright © 2015")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("0171c060-b220-4e4d-af25-2e2fc92e9267")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: ReactiveUI.Fody/ReactiveDependencyPropertyWeaver.cs ================================================ using System; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; namespace ReactiveUI.Fody { public class ReactiveDependencyPropertyWeaver { public ModuleDefinition ModuleDefinition { get; set; } // Will log an MessageImportance.High message to MSBuild. OPTIONAL public Action LogInfo { get; set; } // Will log an error message to MSBuild. OPTIONAL public Action LogError { get; set; } public void Execute() { var reactiveUI = ModuleDefinition.AssemblyReferences.Where(x => x.Name == "ReactiveUI").OrderByDescending(x => x.Version).FirstOrDefault(); if (reactiveUI == null) { LogInfo("Could not find assembly: ReactiveUI (" + string.Join(", ", ModuleDefinition.AssemblyReferences.Select(x => x.Name)) + ")"); return; } LogInfo($"{reactiveUI.Name} {reactiveUI.Version}"); var helpers = ModuleDefinition.AssemblyReferences.Where(x => x.Name == "ReactiveUI.Fody.Helpers").OrderByDescending(x => x.Version).FirstOrDefault(); if (helpers == null) { LogInfo("Could not find assembly: ReactiveUI.Fody.Helpers (" + string.Join(", ", ModuleDefinition.AssemblyReferences.Select(x => x.Name)) + ")"); return; } LogInfo($"{helpers.Name} {helpers.Version}"); var reactiveObject = new TypeReference("ReactiveUI", "IReactiveObject", ModuleDefinition, reactiveUI); var targetTypes = ModuleDefinition.GetAllTypes().Where(x => x.BaseType != null && reactiveObject.IsAssignableFrom(x.BaseType)).ToArray(); var reactiveObjectExtensions = new TypeReference("ReactiveUI", "IReactiveObjectExtensions", ModuleDefinition, reactiveUI).Resolve(); if (reactiveObjectExtensions == null) throw new Exception("reactiveObjectExtensions is null"); var raisePropertyChangedMethod = ModuleDefinition.ImportReference(reactiveObjectExtensions.Methods.Single(x => x.Name == "RaisePropertyChanged")); if (raisePropertyChangedMethod == null) throw new Exception("raisePropertyChangedMethod is null"); var reactiveDependencyAttribute = ModuleDefinition.FindType("ReactiveUI.Fody.Helpers", "ReactiveDependencyAttribute", helpers); if (reactiveDependencyAttribute == null) throw new Exception("reactiveDecoratorAttribute is null"); foreach (var targetType in targetTypes.Where(x => x.Properties.Any(y => y.IsDefined(reactiveDependencyAttribute))).ToArray()) { foreach (var facadeProperty in targetType.Properties.Where(x => x.IsDefined(reactiveDependencyAttribute)).ToArray()) { // If the property already has a body then do not weave to prevent loss of instructions if (!facadeProperty.GetMethod.Body.Instructions.Any(x => x.Operand is FieldReference) || facadeProperty.GetMethod.Body.HasVariables) { LogError($"Property {facadeProperty.Name} is not an auto property and therefore not suitable for ReactiveDependency weaving"); continue; } var attribute = facadeProperty.CustomAttributes.First(x => x.AttributeType.FullName == reactiveDependencyAttribute.FullName); var targetNamedArgument = attribute.ConstructorArguments.FirstOrDefault(); var targetValue = targetNamedArgument.Value?.ToString(); if (string.IsNullOrEmpty(targetValue)) { LogError("No target property defined on the object"); continue; } if (targetType.Properties.All(x => x.Name != targetValue) && targetType.Fields.All(x => x.Name != targetValue)) { LogError($"dependency object property/field name '{targetValue}' not found on target type {targetType.Name}"); continue; } var objPropertyTarget = targetType.Properties.FirstOrDefault(x => x.Name == targetValue); var objFieldTarget = targetType.Fields.FirstOrDefault(x => x.Name == targetValue); var objDependencyTargetType = objPropertyTarget != null ? objPropertyTarget.PropertyType.Resolve() : objFieldTarget?.FieldType.Resolve(); if(objDependencyTargetType == null) { LogError("Couldn't result the dependency type"); continue; } // Look for the target property on the member obj var destinationPropertyNamedArgument = attribute.Properties.FirstOrDefault(x => x.Name == "TargetProperty"); var destinationPropertyName = destinationPropertyNamedArgument.Argument.Value?.ToString(); // If no target property was specified use this property's name as the target on the decorated object (ala a decorated property) if (string.IsNullOrEmpty(destinationPropertyName)) destinationPropertyName = facadeProperty.Name; if (objDependencyTargetType.Properties.All(x => x.Name != destinationPropertyName)) { LogError($"Target property {destinationPropertyName} on dependency of type {objDependencyTargetType.DeclaringType.Name} not found"); continue; } var destinationProperty = objDependencyTargetType.Properties.First(x => x.Name == destinationPropertyName); // The property on the facade/decorator should have a setter if (facadeProperty.SetMethod == null) { LogError($"Property {facadeProperty.DeclaringType.FullName}.{facadeProperty.Name} has no setter, therefore it is not possible for the property to change, and thus should not be marked with [ReactiveDecorator]"); continue; } // The property on the dependency should have a setter e.g. Dependency.SomeProperty = value; if (destinationProperty.SetMethod == null) { LogError($"Dependency object's property {destinationProperty.DeclaringType.FullName}.{destinationProperty.Name} has no setter, therefore it is not possible for the property to change, and thus should not be marked with [ReactiveDecorator]"); continue; } // Remove old field (the generated backing field for the auto property) var oldField = (FieldReference)facadeProperty.GetMethod.Body.Instructions.Where(x => x.Operand is FieldReference).Single().Operand; var oldFieldDefinition = oldField.Resolve(); targetType.Fields.Remove(oldFieldDefinition); // See if there exists an initializer for the auto-property var constructors = targetType.Methods.Where(x => x.IsConstructor); foreach (var constructor in constructors) { var fieldAssignment = constructor.Body.Instructions.SingleOrDefault(x => Equals(x.Operand, oldFieldDefinition) || Equals(x.Operand, oldField)); if (fieldAssignment != null) { // Replace field assignment with a property set (the stack semantics are the same for both, // so happily we don't have to manipulate the bytecode any further.) var setterCall = constructor.Body.GetILProcessor().Create(facadeProperty.SetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, facadeProperty.SetMethod); constructor.Body.GetILProcessor().Replace(fieldAssignment, setterCall); } } // Build out the getter which simply returns the value of the generated field facadeProperty.GetMethod.Body = new MethodBody(facadeProperty.GetMethod); facadeProperty.GetMethod.Body.Emit(il => { il.Emit(OpCodes.Ldarg_0); // this if (objPropertyTarget != null) { il.Emit(objPropertyTarget.GetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, objPropertyTarget.GetMethod); } else { il.Emit(OpCodes.Ldfld, objFieldTarget); } il.Emit(destinationProperty.GetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, destinationProperty.GetMethod); il.Emit(OpCodes.Ret); }); TypeReference genericTargetType = targetType; if (targetType.HasGenericParameters) { var genericDeclaration = new GenericInstanceType(targetType); foreach (var parameter in targetType.GenericParameters) { genericDeclaration.GenericArguments.Add(parameter); } genericTargetType = genericDeclaration; } var methodReference = raisePropertyChangedMethod.MakeGenericMethod(genericTargetType); facadeProperty.SetMethod.Body = new MethodBody(facadeProperty.SetMethod); facadeProperty.SetMethod.Body.Emit(il => { il.Emit(OpCodes.Ldarg_0); if (objPropertyTarget != null) { il.Emit(objPropertyTarget.GetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, objPropertyTarget.GetMethod); } else { il.Emit(OpCodes.Ldfld, objFieldTarget); } il.Emit(OpCodes.Ldarg_1); il.Emit(destinationProperty.SetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, destinationProperty.SetMethod); // Set the nested property il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, facadeProperty.Name); // "PropertyName" il.Emit(OpCodes.Call, methodReference); // this.RaisePropertyChanged("PropertyName") il.Emit(OpCodes.Ret); }); } } } } } ================================================ FILE: ReactiveUI.Fody/ReactiveUI.Fody.csproj ================================================  Debug AnyCPU {CCACB6C3-4C59-4372-85D1-CDDCE0D26989} Library Properties ReactiveUI.Fody ReactiveUI.Fody v4.5 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 6 pdbonly true bin\Release\ TRACE prompt 4 ..\packages\FodyCecil.2.0.9\lib\net40\Mono.Cecil.dll ..\packages\FodyCecil.2.0.9\lib\net40\Mono.Cecil.Mdb.dll ..\packages\FodyCecil.2.0.9\lib\net40\Mono.Cecil.Pdb.dll ..\packages\FodyCecil.2.0.9\lib\net40\Mono.Cecil.Rocks.dll ..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll ..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll ..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll ..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll ..\packages\Rx-XAML.2.2.5\lib\net45\System.Reactive.Windows.Threading.dll ================================================ FILE: ReactiveUI.Fody/ReactiveUIPropertyWeaver.cs ================================================ using System; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Cecil.Rocks; namespace ReactiveUI.Fody { /// /// Weaver that replaces properties marked with `[DataMember]` on subclasses of `ReactiveObject` with an /// implementation that invokes `RaisePropertyChanged` as is required for reaciveui. /// public class ReactiveUIPropertyWeaver { public ModuleDefinition ModuleDefinition { get; set; } // Will log an MessageImportance.High message to MSBuild. OPTIONAL public Action LogInfo { get; set; } // Will log an error message to MSBuild. OPTIONAL public Action LogError { get; set; } public void Execute() { var reactiveUI = ModuleDefinition.AssemblyReferences.Where(x => x.Name == "ReactiveUI").OrderByDescending(x => x.Version).FirstOrDefault(); if (reactiveUI == null) { LogInfo("Could not find assembly: ReactiveUI (" + string.Join(", ", ModuleDefinition.AssemblyReferences.Select(x => x.Name)) + ")"); return; } LogInfo($"{reactiveUI.Name} {reactiveUI.Version}"); var helpers = ModuleDefinition.AssemblyReferences.Where(x => x.Name == "ReactiveUI.Fody.Helpers").OrderByDescending(x => x.Version).FirstOrDefault(); if (helpers == null) { LogInfo("Could not find assembly: ReactiveUI.Fody.Helpers (" + string.Join(", ", ModuleDefinition.AssemblyReferences.Select(x => x.Name)) + ")"); return; } LogInfo($"{helpers.Name} {helpers.Version}"); var reactiveObject = new TypeReference("ReactiveUI", "IReactiveObject", ModuleDefinition, reactiveUI); var targetTypes = ModuleDefinition.GetAllTypes().Where(x => x.BaseType != null && reactiveObject.IsAssignableFrom(x.BaseType)).ToArray(); var reactivePropertyExtensions = ModuleDefinition.FindType("ReactiveUI.Fody.Helpers", "ReactivePropertyExtensions", helpers).Resolve(); if (reactivePropertyExtensions == null) throw new Exception("reactivePropertyExtensions is null"); var raiseAndSetIfChangedMethod = ModuleDefinition.ImportReference(reactivePropertyExtensions.Methods.Single(x => x.Name == "RaiseAndSetIfChanged")); if (raiseAndSetIfChangedMethod == null) throw new Exception("raiseAndSetIfChangedMethod is null"); var reactiveAttribute = ModuleDefinition.FindType("ReactiveUI.Fody.Helpers", "ReactiveAttribute", helpers); if (reactiveAttribute == null) throw new Exception("reactiveAttribute is null"); var reactiveObjectExtensions = new TypeReference("ReactiveUI", "IReactiveObjectExtensions", ModuleDefinition, reactiveUI).Resolve(); if (reactiveObjectExtensions == null) throw new Exception("reactiveObjectExtensions is null"); var raisePropertyChangedMethod = ModuleDefinition.ImportReference(reactiveObjectExtensions.Methods.Single(x => x.Name == "RaisePropertyChanged")); if (raisePropertyChangedMethod == null) throw new Exception("raisePropertyChangedMethod is null"); foreach (var targetType in targetTypes) { var setMethodByGetMethods = targetType.Properties .Where(x => x.SetMethod != null && x.GetMethod != null && x.IsDefined(reactiveAttribute)) .ToDictionary(x => x.GetMethod, x => x.SetMethod); foreach (var property in targetType.Properties.Where(x => x.IsDefined(reactiveAttribute)).ToArray()) { TypeReference genericTargetType = targetType; if (targetType.HasGenericParameters) { var genericDeclaration = new GenericInstanceType(targetType); foreach (var parameter in targetType.GenericParameters) { genericDeclaration.GenericArguments.Add(parameter); } genericTargetType = genericDeclaration; } MethodDefinition[] getMethods; if (property.SetMethod == null && property.GetMethod.TryGetMethodDependencies(out getMethods)) { var setMethodsForGetInstructions = getMethods .Where(x => setMethodByGetMethods.ContainsKey(x)) .Select(x => setMethodByGetMethods[x]) .ToArray(); if (!setMethodsForGetInstructions.Any()) { LogError($"Get only Property {property.DeclaringType.FullName}.{property.Name} has no supported dependent properties. " + $"Only dependent auto properties decorated with the [Reactive] attribute can be weaved to raise property change on {property.Name}"); } var raisePropertyChangedMethodReference = raisePropertyChangedMethod.MakeGenericMethod(genericTargetType); foreach (var method in setMethodsForGetInstructions) { method.Body.Emit(il => { var last = method.Body.Instructions.Last(i => i.OpCode == OpCodes.Ret); il.InsertBefore(last, il.Create(OpCodes.Ldarg_0)); il.InsertBefore(last, il.Create(OpCodes.Ldstr, property.Name)); il.InsertBefore(last, il.Create(OpCodes.Call, raisePropertyChangedMethodReference)); }); } // Move on to next property for the target type continue; } if (property.SetMethod == null) { LogError($"Property {property.DeclaringType.FullName}.{property.Name} has no setter, therefore it is not possible for the property to change, and thus should not be marked with [Reactive]"); continue; } // Declare a field to store the property value var field = new FieldDefinition("$" + property.Name, FieldAttributes.Private, property.PropertyType); targetType.Fields.Add(field); // Remove old field (the generated backing field for the auto property) var oldField = (FieldReference)property.GetMethod.Body.Instructions.Where(x => x.Operand is FieldReference).Single().Operand; var oldFieldDefinition = oldField.Resolve(); targetType.Fields.Remove(oldFieldDefinition); // See if there exists an initializer for the auto-property var constructors = targetType.Methods.Where(x => x.IsConstructor); foreach (var constructor in constructors) { var fieldAssignment = constructor.Body.Instructions.SingleOrDefault(x => Equals(x.Operand, oldFieldDefinition) || Equals(x.Operand, oldField)); if (fieldAssignment != null) { // Replace field assignment with a property set (the stack semantics are the same for both, // so happily we don't have to manipulate the bytecode any further.) var setterCall = constructor.Body.GetILProcessor().Create(property.SetMethod.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, property.SetMethod); constructor.Body.GetILProcessor().Replace(fieldAssignment, setterCall); } } // Build out the getter which simply returns the value of the generated field property.GetMethod.Body = new MethodBody(property.GetMethod); property.GetMethod.Body.Emit(il => { il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldfld, field.BindDefinition(targetType)); // pop -> this.$PropertyName il.Emit(OpCodes.Ret); // Return the field value that is lying on the stack }); var methodReference = raiseAndSetIfChangedMethod.MakeGenericMethod(genericTargetType, property.PropertyType); // Build out the setter which fires the RaiseAndSetIfChanged method if (property.SetMethod == null) { throw new Exception("[Reactive] is decorating " + property.DeclaringType.FullName + "." + property.Name + ", but the property has no setter so there would be nothing to react to. Consider removing the attribute."); } property.SetMethod.Body = new MethodBody(property.SetMethod); property.SetMethod.Body.Emit(il => { RaiseAndSetIfChanged(methodReference, targetType, field, il, property.Name); }); } } } private void RaiseAndSetIfChanged(MethodReference raiseAndSetIfChangedMethod, TypeDefinition targetType, FieldDefinition field, ILProcessor il, string propertyName) { il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Ldflda, field.BindDefinition(targetType)); // pop -> ref this.$PropertyName il.Emit(OpCodes.Ldarg_1); // value il.Emit(OpCodes.Ldstr, propertyName); // "PropertyName" il.Emit(OpCodes.Call, raiseAndSetIfChangedMethod); // pop * 4 -> this.RaiseAndSetIfChanged(this.$PropertyName, value, "PropertyName") il.Emit(OpCodes.Pop); // We don't care about the result of RaiseAndSetIfChanged, so pop it off the stack (stack is now empty) il.Emit(OpCodes.Ret); // Return out of the function } } } ================================================ FILE: ReactiveUI.Fody/packages.config ================================================  ================================================ FILE: ReactiveUI.Fody.Helpers/LogPropertyOnErrorException.cs ================================================ using System; namespace ReactiveUI.Fody.Helpers { public class LogPropertyOnErrorException : Exception { public new object Source { get; } public string Property { get; } public LogPropertyOnErrorException(object source, string property, Exception innerException) : base($"An exception occurred when a property change notification was fired on {source.GetType().FullName}.{property} on an instance of {source.GetType().FullName}: {source}", innerException) { Source = source; Property = property; } } } ================================================ FILE: ReactiveUI.Fody.Helpers/LogPropertyOnErrorObservable.cs ================================================ using System; namespace ReactiveUI.Fody.Helpers { internal class LogPropertyOnErrorObservable : IObservable { private readonly IObservable @this; private readonly object source; private readonly string property; public LogPropertyOnErrorObservable(IObservable @this, object source, string property) { this.@this = @this; this.source = source; this.property = property; } public IDisposable Subscribe(IObserver observer) { return @this.Subscribe(new LogPropertyOnErrorObserver(observer, source, property)); } private class LogPropertyOnErrorObserver : IObserver { private readonly IObserver @this; private readonly object source; private readonly string property; public LogPropertyOnErrorObserver(IObserver @this, object source, string property) { this.@this = @this; this.source = source; this.property = property; } public void OnCompleted() { @this.OnCompleted(); } public void OnError(Exception error) { @this.OnError(new LogPropertyOnErrorException(source, property, error)); } public void OnNext(T value) { @this.OnNext(value); } } } } ================================================ FILE: ReactiveUI.Fody.Helpers/ObservableAsPropertyAttribute.cs ================================================ using System; namespace ReactiveUI.Fody.Helpers { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] public class ObservableAsPropertyAttribute : Attribute { } } ================================================ FILE: ReactiveUI.Fody.Helpers/ObservableAsPropertyExtensions.cs ================================================ using System; using System.Linq.Expressions; using System.Reactive.Concurrency; using System.Reflection; using ReactiveUI.Fody.Helpers.Settings; namespace ReactiveUI.Fody.Helpers { public static class ObservableAsPropertyExtensions { public static ObservableAsPropertyHelper ToPropertyEx(this IObservable @this, TObj source, Expression> property, TRet initialValue = default(TRet), bool deferSubscription = false, IScheduler scheduler = null) where TObj : ReactiveObject { // Now assign the field via reflection. var propertyInfo = property.GetPropertyInfo(); if (propertyInfo == null) throw new Exception("Could not resolve expression " + property + " into a property."); if (GlobalSettings.IsLogPropertyOnErrorEnabled) @this = new LogPropertyOnErrorObservable(@this, source, propertyInfo.Name); var result = @this.ToProperty(source, property, initialValue, deferSubscription, scheduler); var field = propertyInfo.DeclaringType.GetTypeInfo().GetDeclaredField("$" + propertyInfo.Name); if (field == null) throw new Exception("Backing field not found for " + propertyInfo); field.SetValue(source, result); return result; } static PropertyInfo GetPropertyInfo(this LambdaExpression expression) { var current = expression.Body; var unary = current as UnaryExpression; if (unary != null) current = unary.Operand; var call = (MemberExpression)current; return (PropertyInfo)call.Member; } } } ================================================ FILE: ReactiveUI.Fody.Helpers/ReactiveAttribute.cs ================================================ using System; namespace ReactiveUI.Fody.Helpers { [AttributeUsage(AttributeTargets.Property)] public class ReactiveAttribute : Attribute { } } ================================================ FILE: ReactiveUI.Fody.Helpers/ReactiveDependencyAttribute.cs ================================================ using System; using System.Collections.Generic; using System.Text; namespace ReactiveUI.Fody.Helpers { [AttributeUsage(AttributeTargets.Property)] public class ReactiveDependencyAttribute : Attribute { private readonly string _targetName; public ReactiveDependencyAttribute(string targetName) { _targetName = targetName; } /// /// The name of the backing property /// public string Target => _targetName; /// /// Target property on the backing property /// public string TargetProperty { get; set; } } } ================================================ FILE: ReactiveUI.Fody.Helpers/ReactivePropertyExtensions.cs ================================================ using System; using System.Reflection; using ReactiveUI.Fody.Helpers.Settings; namespace ReactiveUI.Fody.Helpers { public static class ReactivePropertyExtensions { public static TRet RaiseAndSetIfChanged(this TObj @this, ref TRet backingField, TRet newValue, string propertyName = null) where TObj : IReactiveObject { if (GlobalSettings.IsLogPropertyOnErrorEnabled) { try { return IReactiveObjectExtensions.RaiseAndSetIfChanged(@this, ref backingField, newValue, propertyName); } catch (Exception ex) { throw new LogPropertyOnErrorException(@this, propertyName, ex); } } else { return IReactiveObjectExtensions.RaiseAndSetIfChanged(@this, ref backingField, newValue, propertyName); } } } } ================================================ FILE: ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.projitems ================================================  $(MSBuildAllProjects);$(MSBuildThisFileFullPath) true 4433ff2e-3150-4d7f-be18-a2258799b79d ReactiveUI.Fody.Helpers ================================================ FILE: ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.shproj ================================================ 4433ff2e-3150-4d7f-be18-a2258799b79d ================================================ FILE: ReactiveUI.Fody.Helpers/Settings/GlobalSettings.cs ================================================ namespace ReactiveUI.Fody.Helpers.Settings { public static class GlobalSettings { public static bool IsLogPropertyOnErrorEnabled { get; set; } } } ================================================ FILE: ReactiveUI.Fody.Helpers.Android/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Android.App; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("ReactiveUI.Fody.Helpers")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ReactiveUI.Fody.Helpers")] [assembly: AssemblyCopyright("Copyright © 2015")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: ReactiveUI.Fody.Helpers.Android/ReactiveUI.Fody.Helpers.Android.csproj ================================================  Debug AnyCPU 8.0.30703 2.0 {6D2A6846-A8B7-4186-807D-12E335BD1C67} {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Library Properties ReactiveUI.Fody.Helpers ReactiveUI.Fody.Helpers 512 Resources\Resource.Designer.cs Off True True v5.0 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\packages\reactiveui-core.7.0.0\lib\portable-net45+netcore45+wpa81+win8+wp8+UAP10+MonoAndroid403+MonoTouch10+Xamarin.iOS10\ReactiveUI.dll True ..\packages\Splat.1.6.0\lib\monoandroid\Splat.dll ..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll ..\packages\Rx-Interfaces.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Interfaces.dll ..\packages\Rx-Linq.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Linq.dll ..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll ================================================ FILE: ReactiveUI.Fody.Helpers.Android/Resources/AboutResources.txt ================================================ Images, layout descriptions, binary blobs and string dictionaries can be included in your application as resource files. Various Android APIs are designed to operate on the resource IDs instead of dealing with images, strings or binary blobs directly. For example, a sample Android app that contains a user interface layout (main.xml), an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) would keep its resources in the "Resources" directory of the application: Resources/ drawable-hdpi/ icon.png drawable-ldpi/ icon.png drawable-mdpi/ icon.png layout/ main.xml values/ strings.xml In order to get the build system to recognize Android resources, set the build action to "AndroidResource". The native Android APIs do not operate directly with filenames, but instead operate on resource IDs. When you compile an Android application that uses resources, the build system will package the resources for distribution and generate a class called "Resource" that contains the tokens for each one of the resources included. For example, for the above Resources layout, this is what the Resource class would expose: public class Resource { public class drawable { public const int icon = 0x123; } public class layout { public const int main = 0x456; } public class strings { public const int first_string = 0xabc; public const int second_string = 0xbcd; } } You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main to reference the layout/main.xml file, or Resource.strings.first_string to reference the first string in the dictionary file values/strings.xml. ================================================ FILE: ReactiveUI.Fody.Helpers.Android/Resources/Resource.Designer.cs ================================================ #pragma warning disable 1591 //------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ [assembly: global::Android.Runtime.ResourceDesignerAttribute("ReactiveUI.Fody.Helpers.Resource", IsApplication=false)] namespace ReactiveUI.Fody.Helpers { [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] public partial class Resource { static Resource() { global::Android.Runtime.ResourceIdManager.UpdateIdValues(); } public partial class Attribute { static Attribute() { global::Android.Runtime.ResourceIdManager.UpdateIdValues(); } private Attribute() { } } public partial class String { // aapt resource value: 0x7f020002 public static int ApplicationName = 2130837506; // aapt resource value: 0x7f020001 public static int Hello = 2130837505; // aapt resource value: 0x7f020000 public static int library_name = 2130837504; static String() { global::Android.Runtime.ResourceIdManager.UpdateIdValues(); } private String() { } } } } #pragma warning restore 1591 ================================================ FILE: ReactiveUI.Fody.Helpers.Android/Resources/Values/Strings.xml ================================================ Hello World, Click Me! $projectname$ ================================================ FILE: ReactiveUI.Fody.Helpers.Android/packages.config ================================================  ================================================ FILE: ReactiveUI.Fody.Helpers.Ios/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("ReactiveUI.Fody.Helpers.Ios")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ReactiveUI.Fody.Helpers.Ios")] [assembly: AssemblyCopyright("Copyright © 2015")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("2986e217-fe12-4070-8926-fe6ac596094e")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: ReactiveUI.Fody.Helpers.Ios/ReactiveUI.Fody.Helpers.Ios.csproj ================================================  Debug iPhoneSimulator 8.0.30703 2.0 {377C39ED-0F7E-4522-A41E-96C5BA0C4FCB} {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Library ReactiveUI.Fody.Helpers Resources ReactiveUI.Fody.Helpers true full false bin\iPhone\Debug DEBUG prompt 4 false true iPhone Developer none true bin\iPhone\Release prompt 4 false iPhone Developer ..\packages\reactiveui-core.7.0.0\lib\portable-net45+netcore45+wpa81+win8+wp8+UAP10+MonoAndroid403+MonoTouch10+Xamarin.iOS10\ReactiveUI.dll True ..\packages\Splat.1.6.0\lib\Xamarin.iOS10\Splat.dll ..\packages\Rx-Core.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Core.dll ..\packages\Rx-Interfaces.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Interfaces.dll ..\packages\Rx-Linq.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.Linq.dll ..\packages\Rx-PlatformServices.2.2.5\lib\portable-windows8+net45+wp8\System.Reactive.PlatformServices.dll ================================================ FILE: ReactiveUI.Fody.Helpers.Ios/packages.config ================================================  ================================================ FILE: ReactiveUI.Fody.Helpers.Net45/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("ReactiveUI.Fody.Helpers.Net45")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ReactiveUI.Fody.Helpers.Net45")] [assembly: AssemblyCopyright("Copyright © 2015")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("525a89d6-cbd1-4776-9692-952d32f01e28")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: ReactiveUI.Fody.Helpers.Net45/ReactiveUI.Fody.Helpers.Net45.csproj ================================================  Debug AnyCPU {1CA52110-BE45-4C45-B709-28061077E2A5} Library Properties ReactiveUI.Fody.Helpers ReactiveUI.Fody.Helpers v4.5 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\packages\reactiveui-core.7.0.0\lib\portable-net45+netcore45+wpa81+win8+wp8+UAP10+MonoAndroid403+MonoTouch10+Xamarin.iOS10\ReactiveUI.dll True ..\packages\Splat.1.6.0\lib\Net45\Splat.dll ..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll ..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll ..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll ..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll ..\packages\Rx-XAML.2.2.5\lib\net45\System.Reactive.Windows.Threading.dll ================================================ FILE: ReactiveUI.Fody.Helpers.Net45/packages.config ================================================  ================================================ FILE: ReactiveUI.Fody.Helpers.Pcl/Properties/AssemblyInfo.cs ================================================ using System.Resources; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("ReactiveUI.Fody.Helpers.Pcl")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ReactiveUI.Fody.Helpers.Pcl")] [assembly: AssemblyCopyright("Copyright © 2015")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: NeutralResourcesLanguage("en")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: ReactiveUI.Fody.Helpers.Pcl/ReactiveUI.Fody.Helpers.Pcl.csproj ================================================  10.0 Debug AnyCPU {8509509A-17C7-4CF0-84AD-5DD208446766} Library Properties ReactiveUI.Fody.Helpers ReactiveUI.Fody.Helpers en-US 512 {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Profile259 v4.5 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\packages\reactiveui-core.7.0.0\lib\portable-net45+netcore45+wpa81+win8+wp8+UAP10+MonoAndroid403+MonoTouch10+Xamarin.iOS10\ReactiveUI.dll True ..\packages\Splat.1.6.0\lib\Portable-net45+win+wpa81+wp80\Splat.dll ..\packages\Rx-Core.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.Core.dll ..\packages\Rx-Interfaces.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.Interfaces.dll ..\packages\Rx-Linq.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.Linq.dll ..\packages\Rx-PlatformServices.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.PlatformServices.dll ================================================ FILE: ReactiveUI.Fody.Helpers.Pcl/packages.config ================================================  ================================================ FILE: ReactiveUI.Fody.Tests/FodyWeavers.xml ================================================ ================================================ FILE: ReactiveUI.Fody.Tests/Issues/Issue10Tests.cs ================================================ using System; using NUnit.Framework; using ReactiveUI.Fody.Helpers; namespace ReactiveUI.Fody.Tests.Issues { [TestFixture] public class Issue10Tests { [Test] public void UninitializedObservableAsPropertyHelperDoesntThrowAndReturnsDefaultValue() { var model = new TestModel(); Assert.AreEqual(null, model.MyProperty); Assert.AreEqual(0, model.MyIntProperty); Assert.AreEqual(default(DateTime), model.MyDateTimeProperty); } class TestModel : ReactiveObject { [ObservableAsProperty] public string MyProperty { get; private set; } [ObservableAsProperty] public int MyIntProperty { get; private set; } [ObservableAsProperty] public DateTime MyDateTimeProperty { get; private set; } public string OtherProperty { get; private set; } public TestModel() { OtherProperty = MyProperty; } } } } ================================================ FILE: ReactiveUI.Fody.Tests/Issues/Issue11Tests.cs ================================================ using System.Reactive.Linq; using NUnit.Framework; using ReactiveUI.Fody.Helpers; namespace ReactiveUI.Fody.Tests.Issues { [TestFixture] public class Issue11Tests { [Test] public void AllowObservableAsPropertyAttributeOnAccessor() { var model = new TestModel("foo"); Assert.AreEqual("foo", model.MyProperty); } public class TestModel : ReactiveObject { public extern string MyProperty { [ObservableAsProperty]get; } public TestModel(string myProperty) { Observable.Return(myProperty).ToPropertyEx(this, x => x.MyProperty); } } } } ================================================ FILE: ReactiveUI.Fody.Tests/Issues/Issue13Tests.cs ================================================ using NUnit.Framework; using ReactiveUI.Fody.Helpers; using System; using System.Collections.Generic; using System.Linq; using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; namespace ReactiveUI.Fody.Tests.Issues { [TestFixture] public class Issue13Tests { [Test] public void AccessingAChainedObservableAsPropertyOfDoubleDoesntThrow() { var vm = new VM(); Assert.AreEqual(0.0, vm.P2); } class VM : ReactiveObject { [ObservableAsProperty] public double P1 { get; } [ObservableAsProperty] public double P2 { get; } public VM() { Observable.Return(0.0).ToPropertyEx(this, vm => vm.P1); this.WhenAnyValue(vm => vm.P1).ToPropertyEx(this, vm => vm.P2); } } } } ================================================ FILE: ReactiveUI.Fody.Tests/Issues/Issue31Tests.cs ================================================ using System; using System.Reactive.Linq; using NUnit.Framework; using ReactiveUI.Fody.Helpers; using GlobalSettings = ReactiveUI.Fody.Helpers.Settings.GlobalSettings; namespace ReactiveUI.Fody.Tests.Issues { [TestFixture] public class Issue31Tests { [Test] public void ExceptionPropertyInfoForReactiveProperty() { try { GlobalSettings.IsLogPropertyOnErrorEnabled = true; try { var model = new ReactivePropertyModel(); model.MyProperty = "foo"; Assert.Fail(); } catch (LogPropertyOnErrorException ex) { Assert.AreEqual(nameof(ObservableAsPropertyModel.MyProperty), ex.Property); } } finally { GlobalSettings.IsLogPropertyOnErrorEnabled = false; } } [Test] public void ExceptionPropertyInfoForObservableAsProperty() { try { GlobalSettings.IsLogPropertyOnErrorEnabled = true; try { new ObservableAsPropertyModel(); Assert.Fail(); } catch (UnhandledErrorException ex) { var propertyException = (LogPropertyOnErrorException)ex.InnerException; Assert.AreEqual(nameof(ObservableAsPropertyModel.MyProperty), propertyException.Property); } } finally { GlobalSettings.IsLogPropertyOnErrorEnabled = false; } } public class ObservableAsPropertyModel : ReactiveObject { public extern string MyProperty { [ObservableAsProperty]get; } public ObservableAsPropertyModel() { Observable.Throw(new Exception("Observable error")).ToPropertyEx(this, x => x.MyProperty); } } public class ReactivePropertyModel : ReactiveObject { [Reactive]public string MyProperty { get; set; } public ReactivePropertyModel() { this.ObservableForProperty(x => x.MyProperty).Subscribe(_ => { throw new Exception("Subscribe error"); }); } } } } ================================================ FILE: ReactiveUI.Fody.Tests/Issues/Issue41Tests.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel; using NUnit.Framework; using ReactiveUI.Fody.Helpers; namespace ReactiveUI.Fody.Tests.Issues { [TestFixture] public class Issue41Tests { [Test] public void PropertyChangedRaisedForDerivedPropertyOnIntPropertySet() { // Arrange var model = new TestModel(); var expectedInpcPropertyName = nameof(TestModel.DerivedProperty); var receivedInpcPropertyNames = new List(); var inpc = (INotifyPropertyChanged) model; inpc.PropertyChanged += (sender, args) => receivedInpcPropertyNames.Add(args.PropertyName); // Act model.IntProperty = 5; // Assert Assert.IsTrue(receivedInpcPropertyNames.Contains(expectedInpcPropertyName)); } [Test] public void PropertyChangedRaisedOnStringPropertySet() { // Arrange var model = new TestModel(); var expectedInpcPropertyName = nameof(TestModel.DerivedProperty); var receivedInpcPropertyNames = new List(); var inpc = (INotifyPropertyChanged) model; inpc.PropertyChanged += (sender, args) => receivedInpcPropertyNames.Add(args.PropertyName); // Act model.StringProperty = "Foo"; // Assert Assert.IsTrue(receivedInpcPropertyNames.Contains(expectedInpcPropertyName)); } [Test] public void PropertyChangedRaisedForDerivedPropertyAndAnotherExpressionBodiedPropertyAndCombinedExpressionBodyPropertyWithAutoPropOnIntPropertySet() { // Arrange var model = new TestModel(); var expectedInpcPropertyName1 = nameof(TestModel.AnotherExpressionBodiedProperty); var expectedInpcPropertyName2 = nameof(TestModel.DerivedProperty); var expectedInpcPropertyName3 = nameof(TestModel.CombinedExpressionBodyPropertyWithAutoProp); var receivedInpcPropertyNames = new List(); var inpc = (INotifyPropertyChanged) model; inpc.PropertyChanged += (sender, args) => receivedInpcPropertyNames.Add(args.PropertyName); // Act model.IntProperty = 5; // Assert Assert.IsTrue(receivedInpcPropertyNames.Contains(expectedInpcPropertyName1)); Assert.IsTrue(receivedInpcPropertyNames.Contains(expectedInpcPropertyName2)); Assert.IsTrue(receivedInpcPropertyNames.Contains(expectedInpcPropertyName3)); } [Test] public void PropertyChangedRaisedForCombinedExpressionBodyPropertyWithAutoPropOnStringPropertySet() { // Arrange var model = new TestModel(); var expectedInpcPropertyName = nameof(TestModel.CombinedExpressionBodyPropertyWithAutoProp); var receivedInpcPropertyNames = new List(); var inpc = (INotifyPropertyChanged)model; inpc.PropertyChanged += (sender, args) => receivedInpcPropertyNames.Add(args.PropertyName); // Act model.StringProperty = "Foo"; // Assert Assert.IsTrue(receivedInpcPropertyNames.Contains(expectedInpcPropertyName)); } [Test] public void PropertyChangedRaisedForCombinedExpressionBodyPropertyWithAutoPropNonReactivePropertyOnIntPropertySet() { // Arrange var model = new TestModel(); var expectedInpcPropertyName = nameof(TestModel.CombinedExpressionBodyPropertyWithAutoPropNonReactiveProperty); var receivedInpcPropertyNames = new List(); var inpc = (INotifyPropertyChanged)model; inpc.PropertyChanged += (sender, args) => receivedInpcPropertyNames.Add(args.PropertyName); // Act model.IntProperty = 5; // Assert Assert.IsTrue(receivedInpcPropertyNames.Contains(expectedInpcPropertyName)); } [Test] // Ensure that this only works with dependent properties that have the [Reactive] attribute public void PropertyChangedNotRaisedForCombinedExpressionBodyPropertyWithAutoPropNonReactivePropertyOnNonReactivePropertySet() { // Arrange var model = new TestModel(); var expectedInpcPropertyName = nameof(TestModel.CombinedExpressionBodyPropertyWithAutoPropNonReactiveProperty); var receivedInpcPropertyNames = new List(); var inpc = (INotifyPropertyChanged)model; inpc.PropertyChanged += (sender, args) => receivedInpcPropertyNames.Add(args.PropertyName); // Act model.NonReactiveProperty = "Foo"; // Assert Assert.IsEmpty(receivedInpcPropertyNames); } class TestModel : ReactiveObject { [Reactive] public int IntProperty { get; set; } [Reactive] public string StringProperty { get; set; } public string NonReactiveProperty { get; set; } [Reactive] // Raise property change when either StringProperty or IntProperty are set public string DerivedProperty => StringProperty + IntProperty; [Reactive] // Raise property change when IntProperty is set public int AnotherExpressionBodiedProperty => IntProperty; [Reactive] // Raise property changed when StringProperty or IntProperty is set (as AnotherExpressionBodiedProperty is dependent upon IntProperty) public string CombinedExpressionBodyPropertyWithAutoProp => AnotherExpressionBodiedProperty + StringProperty; [Reactive] public string CombinedExpressionBodyPropertyWithAutoPropNonReactiveProperty => CombinedExpressionBodyPropertyWithAutoProp + NonReactiveProperty; } } } ================================================ FILE: ReactiveUI.Fody.Tests/Issues/Issue47Tests.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ReactiveUI.Fody.Helpers; namespace ReactiveUI.Fody.Tests.Issues { public class Issue47Tests { /// /// The "test" here is simply for these to compile /// Tests ObservableAsPropertyWeaver.EmitDefaultValue /// class TestModel : ReactiveObject { public extern int IntProperty { [ObservableAsProperty] get; } public extern double DoubleProperty { [ObservableAsProperty] get; } public extern float FloatProperty { [ObservableAsProperty] get; } public extern long LongProperty { [ObservableAsProperty] get; } } } } ================================================ FILE: ReactiveUI.Fody.Tests/ObservableAsPropertyTests.cs ================================================ using System.Reactive.Linq; using NUnit.Framework; using ReactiveUI.Fody.Helpers; namespace ReactiveUI.Fody.Tests { public class ObservableAsPropertyTests { [Test] public void TestPropertyReturnsFoo() { var model = new TestModel(); Assert.AreEqual("foo", model.TestProperty); } class TestModel : ReactiveObject { [ObservableAsProperty] public string TestProperty { get; private set; } public TestModel() { Observable.Return("foo").ToPropertyEx(this, x => x.TestProperty); } } } } ================================================ FILE: ReactiveUI.Fody.Tests/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("ReactiveUI.Fody.Tests")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ReactiveUI.Fody.Tests")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("a735c110-6877-4c3a-8056-9abc5fb2dd91")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] ================================================ FILE: ReactiveUI.Fody.Tests/ReactiveDependencyTests.cs ================================================ using System; using System.ComponentModel; using NUnit.Framework; using ReactiveUI.Fody.Helpers; namespace ReactiveUI.Fody.Tests { public class ReactiveDependencyTests { [Test] public void IntPropertyOnWeavedFacadeReturnsBaseModelIntPropertyDefaultValueTest() { var model = new BaseModel(); var expectedResult = model.IntProperty; var facade = new FacadeModel(model); Assert.AreEqual(expectedResult, facade.IntProperty); } [Test] public void AnotherStringPropertyOnFacadeReturnsBaseModelStringPropertyDefaultValueTest() { var model = new BaseModel(); var expectedResult = model.StringProperty; var facade = new FacadeModel(model); Assert.AreEqual(expectedResult, facade.AnotherStringProperty); } [Test] public void SettingAnotherStringPropertyUpdatesTheDependencyStringProperty() { var expectedResult = "New String Value"; var facade = new FacadeModel(new BaseModel()); facade.AnotherStringProperty = expectedResult; Assert.AreEqual(expectedResult, facade.Dependency.StringProperty); } [Test] public void SettingFacadeIntPropertyUpdatesDependencyIntProperty() { var expectedResult = 999; var facade = new FacadeModel(new BaseModel()); facade.IntProperty = expectedResult; Assert.AreEqual(expectedResult, facade.Dependency.IntProperty); } [Test] public void FacadeIntPropertyChangedEventFiresOnAssignementTest() { var expectedPropertyChanged = "IntProperty"; var resultPropertyChanged = string.Empty; var facade = new FacadeModel(new BaseModel()); var obj = (INotifyPropertyChanged) facade; obj.PropertyChanged += (sender, args) => resultPropertyChanged = args.PropertyName; facade.IntProperty = 999; Assert.AreEqual(expectedPropertyChanged, resultPropertyChanged); } [Test] public void FacadeAnotherStringPropertyChangedEventFiresOnAssignementTest() { var expectedPropertyChanged = "AnotherStringProperty"; var resultPropertyChanged = string.Empty; var facade = new FacadeModel(new BaseModel()); var obj = (INotifyPropertyChanged) facade; obj.PropertyChanged += (sender, args) => resultPropertyChanged = args.PropertyName; facade.AnotherStringProperty = "Some New Value"; Assert.AreEqual(expectedPropertyChanged, resultPropertyChanged); } [Test] public void StringPropertyOnWeavedDecoratorReturnsBaseModelDefaultStringValue() { var model = new BaseModel(); var expectedResult = model.StringProperty; var decorator = new DecoratorModel(model); Assert.AreEqual(expectedResult, decorator.StringProperty); } [Test] public void DecoratorStringPropertyRaisesPropertyChanged() { var expectedPropertyChanged = "StringProperty"; var resultPropertyChanged = string.Empty; var decorator = new DecoratorModel(new BaseModel()); var obj = (INotifyPropertyChanged) decorator; obj.PropertyChanged += (sender, args) => resultPropertyChanged = args.PropertyName; decorator.StringProperty = "Some New Value"; Assert.AreEqual(expectedPropertyChanged, resultPropertyChanged); } } public class BaseModel : ReactiveObject { public virtual int IntProperty { get; set; } = 5; public virtual string StringProperty { get; set; } = "Initial Value"; } public class FacadeModel : ReactiveObject { private BaseModel _dependency; public FacadeModel() { _dependency = new BaseModel(); } public FacadeModel(BaseModel dependency) { _dependency = dependency; } public BaseModel Dependency { get { return _dependency; } private set { _dependency = value; } } // Property with the same name, will look for a like for like name on the named dependency [ReactiveDependency(nameof(Dependency))] public int IntProperty { get; set; } // Property named differently to that on the dependency but still pass through value [ReactiveDependency(nameof(Dependency), TargetProperty = "StringProperty")] public string AnotherStringProperty { get; set; } } public class DecoratorModel : BaseModel { private readonly BaseModel _model; // Testing ctor public DecoratorModel() { _model = new BaseModel(); } public DecoratorModel(BaseModel baseModel) { _model = baseModel; } [Reactive] public string SomeCoolNewProperty { get; set; } // Works with private fields [ReactiveDependency(nameof(_model))] public override string StringProperty { get; set; } // Can't be attributed as has additional functionality in the decorated get public override int IntProperty { get { return _model.IntProperty * 2; } set { _model.IntProperty = value; this.RaisePropertyChanged(); } } } } ================================================ FILE: ReactiveUI.Fody.Tests/ReactiveUI.Fody.Tests.csproj ================================================  Debug AnyCPU {A735C110-6877-4C3A-8056-9ABC5FB2DD91} Library Properties ReactiveUI.Fody.Tests ReactiveUI.Fody.Tests v4.5 512 true full false bin\Debug\ DEBUG;TRACE prompt 4 pdbonly true bin\Release\ TRACE prompt 4 ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll True ..\packages\reactiveui-core.7.0.0\lib\Net45\ReactiveUI.dll True ..\packages\Splat.1.6.0\lib\Net45\Splat.dll True ..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll True ..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll True ..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll True ..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll True ..\packages\Rx-XAML.2.2.5\lib\net45\System.Reactive.Windows.Threading.dll True Designer Designer {1ca52110-be45-4c45-b709-28061077e2a5} ReactiveUI.Fody.Helpers.Net45 copy $(SolutionDir)ReactiveUI.Fody\bin\$(ConfigurationName)\ReactiveUI.Fody.dll $(SolutionDir)Weavers\bin\Weavers.dll copy $(SolutionDir)ReactiveUI.Fody\bin\$(ConfigurationName)\ReactiveUI.Fody.pdb $(SolutionDir)Weavers\bin\Weavers.pdb This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. ================================================ FILE: ReactiveUI.Fody.Tests/packages.config ================================================  ================================================ FILE: ReactiveUIFody.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody", "ReactiveUI.Fody\ReactiveUI.Fody.csproj", "{CCACB6C3-4C59-4372-85D1-CDDCE0D26989}" EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ReactiveUI.Fody.Helpers", "ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.shproj", "{4433FF2E-3150-4D7F-BE18-A2258799B79D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody.Helpers.Net45", "ReactiveUI.Fody.Helpers.Net45\ReactiveUI.Fody.Helpers.Net45.csproj", "{1CA52110-BE45-4C45-B709-28061077E2A5}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody.Helpers.Pcl", "ReactiveUI.Fody.Helpers.Pcl\ReactiveUI.Fody.Helpers.Pcl.csproj", "{8509509A-17C7-4CF0-84AD-5DD208446766}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{841EF03D-D23E-45CB-8BF5-362F32225C96}" ProjectSection(SolutionItems) = preProject .nuget\packages.config = .nuget\packages.config EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody.Tests", "ReactiveUI.Fody.Tests\ReactiveUI.Fody.Tests.csproj", "{A735C110-6877-4C3A-8056-9ABC5FB2DD91}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.projitems*{1ca52110-be45-4c45-b709-28061077e2a5}*SharedItemsImports = 4 ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.projitems*{4433ff2e-3150-4d7f-be18-a2258799b79d}*SharedItemsImports = 13 ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.projitems*{8509509a-17c7-4cf0-84ad-5dd208446766}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {CCACB6C3-4C59-4372-85D1-CDDCE0D26989}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CCACB6C3-4C59-4372-85D1-CDDCE0D26989}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCACB6C3-4C59-4372-85D1-CDDCE0D26989}.Release|Any CPU.ActiveCfg = Release|Any CPU {CCACB6C3-4C59-4372-85D1-CDDCE0D26989}.Release|Any CPU.Build.0 = Release|Any CPU {1CA52110-BE45-4C45-B709-28061077E2A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1CA52110-BE45-4C45-B709-28061077E2A5}.Debug|Any CPU.Build.0 = Debug|Any CPU {1CA52110-BE45-4C45-B709-28061077E2A5}.Release|Any CPU.ActiveCfg = Release|Any CPU {1CA52110-BE45-4C45-B709-28061077E2A5}.Release|Any CPU.Build.0 = Release|Any CPU {8509509A-17C7-4CF0-84AD-5DD208446766}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8509509A-17C7-4CF0-84AD-5DD208446766}.Debug|Any CPU.Build.0 = Debug|Any CPU {8509509A-17C7-4CF0-84AD-5DD208446766}.Release|Any CPU.ActiveCfg = Release|Any CPU {8509509A-17C7-4CF0-84AD-5DD208446766}.Release|Any CPU.Build.0 = Release|Any CPU {A735C110-6877-4C3A-8056-9ABC5FB2DD91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A735C110-6877-4C3A-8056-9ABC5FB2DD91}.Debug|Any CPU.Build.0 = Debug|Any CPU {A735C110-6877-4C3A-8056-9ABC5FB2DD91}.Release|Any CPU.ActiveCfg = Release|Any CPU {A735C110-6877-4C3A-8056-9ABC5FB2DD91}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: ReactiveUIFody.sln.DotSettings ================================================  DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW DO_NOT_SHOW ================================================ FILE: ReactiveUIFodyAll.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody", "ReactiveUI.Fody\ReactiveUI.Fody.csproj", "{CCACB6C3-4C59-4372-85D1-CDDCE0D26989}" EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ReactiveUI.Fody.Helpers", "ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.shproj", "{4433FF2E-3150-4D7F-BE18-A2258799B79D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody.Helpers.Net45", "ReactiveUI.Fody.Helpers.Net45\ReactiveUI.Fody.Helpers.Net45.csproj", "{1CA52110-BE45-4C45-B709-28061077E2A5}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody.Helpers.Android", "ReactiveUI.Fody.Helpers.Android\ReactiveUI.Fody.Helpers.Android.csproj", "{6D2A6846-A8B7-4186-807D-12E335BD1C67}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody.Helpers.Ios", "ReactiveUI.Fody.Helpers.Ios\ReactiveUI.Fody.Helpers.Ios.csproj", "{377C39ED-0F7E-4522-A41E-96C5BA0C4FCB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody.Helpers.Pcl", "ReactiveUI.Fody.Helpers.Pcl\ReactiveUI.Fody.Helpers.Pcl.csproj", "{8509509A-17C7-4CF0-84AD-5DD208446766}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{841EF03D-D23E-45CB-8BF5-362F32225C96}" ProjectSection(SolutionItems) = preProject .nuget\packages.config = .nuget\packages.config EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Fody.Tests", "ReactiveUI.Fody.Tests\ReactiveUI.Fody.Tests.csproj", "{A735C110-6877-4C3A-8056-9ABC5FB2DD91}" ProjectSection(ProjectDependencies) = postProject {CCACB6C3-4C59-4372-85D1-CDDCE0D26989} = {CCACB6C3-4C59-4372-85D1-CDDCE0D26989} EndProjectSection EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.projitems*{1ca52110-be45-4c45-b709-28061077e2a5}*SharedItemsImports = 4 ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.projitems*{377c39ed-0f7e-4522-a41e-96c5ba0c4fcb}*SharedItemsImports = 4 ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.projitems*{8509509a-17c7-4cf0-84ad-5dd208446766}*SharedItemsImports = 4 ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.projitems*{4433ff2e-3150-4d7f-be18-a2258799b79d}*SharedItemsImports = 13 ReactiveUI.Fody.Helpers\ReactiveUI.Fody.Helpers.projitems*{6d2a6846-a8b7-4186-807d-12e335bd1c67}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {CCACB6C3-4C59-4372-85D1-CDDCE0D26989}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CCACB6C3-4C59-4372-85D1-CDDCE0D26989}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCACB6C3-4C59-4372-85D1-CDDCE0D26989}.Release|Any CPU.ActiveCfg = Release|Any CPU {CCACB6C3-4C59-4372-85D1-CDDCE0D26989}.Release|Any CPU.Build.0 = Release|Any CPU {1CA52110-BE45-4C45-B709-28061077E2A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1CA52110-BE45-4C45-B709-28061077E2A5}.Debug|Any CPU.Build.0 = Debug|Any CPU {1CA52110-BE45-4C45-B709-28061077E2A5}.Release|Any CPU.ActiveCfg = Release|Any CPU {1CA52110-BE45-4C45-B709-28061077E2A5}.Release|Any CPU.Build.0 = Release|Any CPU {6D2A6846-A8B7-4186-807D-12E335BD1C67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6D2A6846-A8B7-4186-807D-12E335BD1C67}.Debug|Any CPU.Build.0 = Debug|Any CPU {6D2A6846-A8B7-4186-807D-12E335BD1C67}.Release|Any CPU.ActiveCfg = Release|Any CPU {6D2A6846-A8B7-4186-807D-12E335BD1C67}.Release|Any CPU.Build.0 = Release|Any CPU {377C39ED-0F7E-4522-A41E-96C5BA0C4FCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {377C39ED-0F7E-4522-A41E-96C5BA0C4FCB}.Debug|Any CPU.Build.0 = Debug|Any CPU {377C39ED-0F7E-4522-A41E-96C5BA0C4FCB}.Release|Any CPU.ActiveCfg = Release|Any CPU {377C39ED-0F7E-4522-A41E-96C5BA0C4FCB}.Release|Any CPU.Build.0 = Release|Any CPU {8509509A-17C7-4CF0-84AD-5DD208446766}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8509509A-17C7-4CF0-84AD-5DD208446766}.Debug|Any CPU.Build.0 = Debug|Any CPU {8509509A-17C7-4CF0-84AD-5DD208446766}.Release|Any CPU.ActiveCfg = Release|Any CPU {8509509A-17C7-4CF0-84AD-5DD208446766}.Release|Any CPU.Build.0 = Release|Any CPU {A735C110-6877-4C3A-8056-9ABC5FB2DD91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A735C110-6877-4C3A-8056-9ABC5FB2DD91}.Debug|Any CPU.Build.0 = Debug|Any CPU {A735C110-6877-4C3A-8056-9ABC5FB2DD91}.Release|Any CPU.ActiveCfg = Release|Any CPU {A735C110-6877-4C3A-8056-9ABC5FB2DD91}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ================================================ FILE: Readme.md ================================================ # ReactiveUI.Fody [![Windows Build Status]](https://ci.appveyor.com/project/KirkWoll/reactiveui-fody) C# Fody extension to generate RaisePropertyChange notifications for properties and ObservableAsPropertyHelper properties. ## Install ## Nuget package ReactiveUI.Fody: > Install-Package ReactiveUI.Fody Currently, you need to manually add `` to your Fody weavers configuration. If this is your first Fody plugin then `FodyWeavers.xml` should look like this after the change: ##Reactive Properties## Eases the need for boilerplate in your view models when using [reactiveui](https://github.com/reactiveui/ReactiveUI). Typically, in your view models you must declare properties like this: string _SearchId; public string SearchId { get { return _SearchId; } set { this.RaiseAndSetIfChanged(ref _SearchId, value); } } This is tedious since all you'd like to do is declare properties as normal: [Reactive]public string SearchId { get; set; } If a property is annotated with the `[Reactive]` attribute, the plugin will weave the boilerplate into your output based on the simple auto-property declaration you provide. ##ObservableAsPropertyHelper Properties Similarly, in order to handle observable property helper properties, you must declare them like this: ObservableAsPropertyHelper _PersonInfo; public string PersonInfo { get { return _PersonInfo.Value; } } Then elsewhere you'd set it up via: ... .ToProperty(this, x => x.PersonInfo, out _PersonInfo); This plugin will instead allow you to declare the property like: public extern string PersonInfo { [ObservableAsProperty]get; } It will generate the field and implement the property for you. Because there is no field for you to pass to `.ToProperty`, you should use the `.ToPropertyEx` extension method provided by this library: ... .ToPropertyEx(this, x => x.PersonInfo); This extension will assign the auto-generated field for you rather than relying on the `out` parameter. [Windows Build Status]: https://ci.appveyor.com/api/projects/status/github/kswoll/ReactiveUI.Fody?svg=true ================================================ FILE: Weavers/bin/_._ ================================================ ================================================ FILE: makepackage.bat ================================================ REM "C:\Program Files (x86)\MSBuild\14.0\Bin\msbuild.exe" ReactiveUIFody.sln cd Nuget ..\packages\NugetUtilities.1.0.5\UpdateVersion.exe ReactiveUIFody.nuspec -Increment mkdir build cd build copy ..\Nuget.exe . copy ..\ReactiveUIFody.nuspec . mkdir lib mkdir lib\net45 mkdir lib\Xamarin.iOS10 mkdir lib\MonoAndroid mkdir "lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10" copy ..\..\ReactiveUI.Fody\bin\Debug\ReactiveUI.Fody.* . REM copy ..\..\ReactiveUI.Fody.Helpers.Ios\bin\iPhone\Debug\ReactiveUI.Fody.Helpers.* lib\Xamarin.iOS10 copy ..\..\ReactiveUI.Fody.1.0.26\lib\Xamarin.iOS10\ReactiveUI.Fody.Helpers.* lib\Xamarin.iOS10 copy ..\..\ReactiveUI.Fody.Helpers.Net45\bin\Debug\ReactiveUI.Fody.Helpers.* lib\net45 copy ..\..\ReactiveUI.Fody.Helpers.Pcl\bin\Debug\ReactiveUI.Fody.Helpers.* "lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10" REM copy ..\..\ReactiveUI.Fody.Helpers.Android\bin\Debug\ReactiveUI.Fody.Helpers.* lib\MonoAndroid copy ..\..\ReactiveUI.Fody.1.0.26\lib\MonoAndroid\ReactiveUI.Fody.Helpers.* lib\MonoAndroid nuget pack ReactiveUIFody.nuspec copy *.nupkg .. cd .. rmdir build /S /Q cd ..