Exemplo n.º 1
0
        string getPropertyValidationError(string propName)
        {
            PropertyExtraInfo pei;

            lock (allValidatedProperties) {
                if (!allValidatedProperties.Get(this.GetType()).TryGetValue(propName, out pei))
                {
                    return(null);
                }
            }

            foreach (var v in pei.ValidationAttributes)
            {
                try {
                    var ctx = new ValidationContext(this, null, null)
                    {
                        MemberName = propName
                    };
                    var pi = RxApp.getPropertyInfoForProperty(pei.Type, propName);
                    v.Validate(pi.GetValue(this, null), ctx);
                } catch (Exception ex) {
                    this.Log().InfoFormat("{0:X}.{1} failed validation: {2}",
                                          this.GetHashCode(), propName, ex.Message);
                    return(ex.Message);
                }
            }

            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Given a fully filled-out IObservedChange object, SetValueToProperty
        /// will apply it to the specified object (i.e. it will ensure that
        /// target.property == This.GetValue() and "replay" the observed change
        /// onto another object)
        /// </summary>
        /// <param name="target">The target object to apply the change to.</param>
        /// <param name="property">The target property to apply the change to.</param>
        public static void SetValueToProperty <TSender, TValue, TTarget>(
            this IObservedChange <TSender, TValue> This,
            TTarget target,
            Expression <Func <TTarget, TValue> > property)
        {
            object current = target;

            string[] propNames = RxApp.expressionToPropertyNames(property);

            PropertyInfo pi;

            foreach (var propName in propNames.SkipLast(1))
            {
                pi      = RxApp.getPropertyInfoOrThrow(current.GetType(), propName);
                current = pi.GetValue(current, null);
            }

            pi = RxApp.getPropertyInfoForProperty(current.GetType(), propNames.Last());
            pi.SetValue(current, This.GetValue(), null);
        }
Exemplo n.º 3
0
        public static PropertyExtraInfo CreateFromTypeAndName(Type type, string propertyName, bool nullOnEmptyValidationAttrs = false)
        {
            object[] attrs;
            var      pi = RxApp.getPropertyInfoForProperty(type, propertyName);

            if (pi == null)
            {
                throw new ArgumentException("Property not found on type");
            }

            attrs = pi.GetCustomAttributes(typeof(ValidationAttribute), true) ?? new ValidationAttribute[0];
            if (nullOnEmptyValidationAttrs && attrs.Length == 0)
            {
                return(null);
            }

            return(new PropertyExtraInfo()
            {
                Type = type,
                PropertyName = propertyName,
                ValidationAttributes = attrs.Cast <ValidationAttribute>().ToArray(),
            });
        }
Exemplo n.º 4
0
        static void subscribeToExpressionChain <TSender, TValue>(
            TSender origSource,
            string origPath,
            object source,
            LinkedListNode <string> propertyNames,
            LinkedListNode <IDisposable> subscriptions,
            bool beforeChange,
            Subject <IObservedChange <TSender, TValue> > subject
            )
        {
            var          current    = propertyNames;
            var          currentSub = subscriptions;
            object       currentObj = source;
            PropertyInfo pi         = null;
            ObservedChange <TSender, TValue> obsCh;

            while (current.Next != null)
            {
                pi = RxApp.getPropertyInfoForProperty(currentObj.GetType(), current.Value);
                if (pi == null)
                {
                    subscriptions.List.Where(x => x != null).ForEach(x => x.Dispose());
                    throw new ArgumentException(String.Format("Property '{0}' does not exist in expression", current.Value));
                }

                var notifyObj = wrapInpcObjectIfNeeded(currentObj);
                if (notifyObj != null)
                {
                    var capture   = new { current, currentObj, pi, currentSub };
                    var toDispose = new IDisposable[2];

                    var valGetter = new ObservedChange <object, TValue>()
                    {
                        Sender       = capture.currentObj,
                        PropertyName = buildPropPathFromNodePtr(capture.current),
                        Value        = default(TValue),
                    };

                    TValue prevVal    = default(TValue);
                    bool   prevValSet = valGetter.TryGetValue(out prevVal);

                    toDispose[0] = notifyObj.Changing.Where(x => x.PropertyName == capture.current.Value).Subscribe(x => {
                        prevValSet = valGetter.TryGetValue(out prevVal);
                    });

                    toDispose[1] = notifyObj.Changed.Where(x => x.PropertyName == capture.current.Value).Subscribe(x => {
                        subscribeToExpressionChain(origSource, origPath, capture.pi.GetValue(capture.currentObj, null), capture.current.Next, capture.currentSub.Next, beforeChange, subject);

                        TValue newVal;
                        if (!valGetter.TryGetValue(out newVal))
                        {
                            return;
                        }

                        if (prevValSet && EqualityComparer <TValue> .Default.Equals(prevVal, newVal))
                        {
                            return;
                        }

                        obsCh = new ObservedChange <TSender, TValue>()
                        {
                            Sender       = origSource,
                            PropertyName = origPath,
                            Value        = default(TValue),
                        };

                        TValue obsChVal;
                        if (obsCh.TryGetValue(out obsChVal))
                        {
                            obsCh.Value = obsChVal;
                            subject.OnNext(obsCh);
                        }
                    });

                    currentSub.Value = Disposable.Create(() => { toDispose[0].Dispose(); toDispose[1].Dispose(); });
                }

                current    = current.Next;
                currentSub = currentSub.Next;
                currentObj = pi.GetValue(currentObj, null);
            }

            var finalNotify = wrapInpcObjectIfNeeded(currentObj);

            if (currentSub.Value != null)
            {
                currentSub.Value.Dispose();
            }

            if (finalNotify == null)
            {
                return;
            }

            var propName = current.Value;

            pi = RxApp.getPropertyInfoForProperty(currentObj.GetType(), current.Value);

            currentSub.Value = (beforeChange ? finalNotify.Changing : finalNotify.Changed).Where(x => x.PropertyName == propName).Subscribe(x => {
                obsCh = new ObservedChange <TSender, TValue>()
                {
                    Sender       = origSource,
                    PropertyName = origPath,
                    Value        = (TValue)pi.GetValue(currentObj, null),
                };

                subject.OnNext(obsCh);
            });
        }