public void FastReflectionProperties() { var fastReflection = new FastReflection(); var testValue = new MockValue(); Assert.AreEqual(1, fastReflection.GetProperty(testValue, nameof(MockValue.Foo))); Assert.AreEqual(2, fastReflection.GetProperty(testValue, nameof(MockValue.Bar))); try { fastReflection.GetProperty(testValue, nameof(MockValue.Boo)); Assert.Fail(); } catch (MemberAccessException) { } catch { Assert.Fail(); } try { fastReflection.GetProperty(testValue, "Buzz"); Assert.Fail(); } catch (MemberAccessException) { } catch { Assert.Fail(); } testValue = new MockValue(); fastReflection.SetProperty(testValue, nameof(MockValue.Foo), 123); Assert.AreEqual(123, fastReflection.GetProperty(testValue, nameof(MockValue.Foo))); try { fastReflection.SetProperty(testValue, nameof(MockValue.Bar), 123); Assert.Fail(); } catch (MemberAccessException) { } catch { Assert.Fail(); } }
public static IMergeableOperation ToOperation <T, TProperty>(this T @this, Expression <Func <T, TProperty> > selector) { var propertyName = selector.GetMemberName(); var currentValue = FastReflection.GetProperty <TProperty>(@this, propertyName); return(GenerateSetPropertyOperation(@this, propertyName, currentValue, Operation.DefaultMergeSpan)); }
public IPropertyBuilder Register <T>(string propertyName) { if (FastReflection.ExistsSetter(Object, propertyName) is false) { RegisterReadOnly(() => FastReflection.GetProperty <T>(Object, propertyName)); } else { Register( () => FastReflection.GetProperty <T>(Object, propertyName), (x) => { FastReflection.SetProperty(Object, propertyName, x); }); } _properties[_properties.Count - 1].Name = propertyName; return(this); }
public static IDisposable BindPropertyChanged <T>(this IOperationController controller, INotifyPropertyChanged owner, string propertyName, bool autoMerge = true) { var prevValue = FastReflection.GetProperty <T>(owner, propertyName); var callFromOperation = false; owner.PropertyChanged += PropertyChanged; return(new Disposer(() => owner.PropertyChanged -= PropertyChanged)); // local function void PropertyChanged(object sender, PropertyChangedEventArgs args) { if (callFromOperation) { return; } if (args.PropertyName == propertyName) { callFromOperation = true; T newValue = FastReflection.GetProperty <T>(owner, propertyName); var operation = owner .GenerateAutoMergeOperation(propertyName, newValue, prevValue, $"{sender.GetHashCode()}.{propertyName}", Operation.DefaultMergeSpan); if (autoMerge) { operation = operation.Merge(controller); } operation .AddPreEvent(() => callFromOperation = true) .AddPostEvent(() => callFromOperation = false); prevValue = newValue; controller.Push(operation); callFromOperation = false; } } }
public static IOperation GenerateSetOperation <T, TProperty>(this T _this, string propertyName, TProperty newValue) { var oldValue = (TProperty)FastReflection.GetProperty(_this, propertyName); return(GenerateAutoMergeOperation(_this, propertyName, newValue, oldValue, $"{_this.GetHashCode()}.{propertyName}")); }
/// <summary> /// プロパティ名からプロパティ設定オペレーションを作成する /// </summary> public static IMergeableOperation GenerateSetPropertyOperation <TProperty>(this object @this, string propertyName, TProperty newValue, TimeSpan timeSpan) { var oldValue = (TProperty)FastReflection.GetProperty(@this, propertyName); return(GenerateAutoMergeOperation(@this, propertyName, newValue, oldValue, $"{@this.GetHashCode()}.{propertyName}", timeSpan)); }
//TODO 整理 public ReflectionPropertyBuilder GenerateProperties() { _suBuilders.Clear(); var bindingFlags = BindingFlags.Instance | BindingFlags.Public; var objectType = Object.GetType(); if (_cache.TryGetValue(objectType, out var properties) is false) { properties = _cache[objectType] = objectType.GetProperties(bindingFlags); } Debug.Assert(properties != null); var propertyNames = properties.Select(x => x.Name).ToArray(); foreach (var propertyName in propertyNames) { var propertyType = FastReflection.GetPropertyType(Object, propertyName); if (propertyType.GetInterfaces().Contains(typeof(ICollection))) { var list = FastReflection.GetProperty <ICollection>(Object, propertyName).ToArray <object>(); var index = 0; var group = new List <IProperty>(); var basicTypeBuilder = new PropertyBuilder(null).OperationController(_operationController); foreach (var value in list) { var subBuilder = new ReflectionPropertyBuilder(value); var properies = subBuilder .GenerateProperties() .OperationController(_operationController) .Build() .ToArray(); if (properies.Any()) { group.Add(properies.ToStructuredProperty($"{propertyName}[{index++}]")); _suBuilders.Add(subBuilder); } else { FastReflection.InvokeGenericMethod(basicTypeBuilder, value.GetType(), nameof(Register), list, index++, propertyName); } } if (group.Any()) { _properties.Add(group.ToGroupProperty(propertyName)); } else { var basic = basicTypeBuilder .Build().ToArray(); if (basic.Any()) { _properties.Add(basic.ToGroupProperty(propertyName)); _suBuilders.Add(basicTypeBuilder); } } } else if (BindablePropertyFactory.Contain(propertyType) == false) { var value = FastReflection.GetProperty(Object, propertyName); if (value is null) { _properties.Add(new ReadOnlyProperty("null") { Name = propertyName }); continue; } var subBuilder = new ReflectionPropertyBuilder(value); var properies = subBuilder .GenerateProperties() .OperationController(_operationController) .Build().ToArray(); if (properies.Any()) { _properties.Add(properies.ToStructuredProperty($"{propertyName}({propertyType.Name})")); _suBuilders.Add(subBuilder); } else { FastReflection.InvokeGenericMethod(this, propertyType, nameof(Register), propertyName); } } else { FastReflection.InvokeGenericMethod(this, propertyType, nameof(Register), propertyName); } } return(this); }