protected override void initialize()
        {
            MemberExpression memberExpression = (MemberExpression)_propertyExpression.Body;

            PropertyInfo      propertyInfo = (PropertyInfo)((MemberExpression)_propertyExpression.Body).Member;
            PropertyAccessors propertyAcessors;

            if (!_propertyAccessors.TryGetValue(propertyInfo, out propertyAcessors))
            {
                ParameterExpression valueParameterExpression  = Expression.Parameter(typeof(TResult));
                ParameterExpression holderParameterExpression = Expression.Parameter(typeof(THolder));
                var setter = Expression.Lambda <Action <THolder, TResult> >(
                    Expression.Assign(Expression.Property(holderParameterExpression, propertyInfo), valueParameterExpression),
                    holderParameterExpression, valueParameterExpression).Compile();

                var getter = Expression.Lambda <Func <THolder, TResult> >(
                    Expression.Property(holderParameterExpression, propertyInfo),
                    holderParameterExpression).Compile();

                propertyAcessors = new PropertyAccessors(getter, setter);
                _propertyAccessors.TryAdd(propertyInfo, propertyAcessors);
            }

            _getter         = propertyAcessors.Getter;
            _setter         = propertyAcessors.Setter;
            _setValueAction = value =>
            {
                void set() => _setter(_propertyHolder, value);

                if (_sourceDispatcher != null)
                {
                    _sourceDispatcher.Invoke(set, this);
                }
                else if (_propertySourceDispatcher != null)
                {
                    _propertySourceDispatcher.Invoke(set, this, false, value);
                }
                else
                {
                    set();
                }
            };

            _propertyHolder = (THolder)((ConstantExpression)memberExpression.Expression).Value;

            void readAndSubscribe()
            {
                TResult value = getValue();

                _propertyHolder.PropertyChanged += handlePropertyHolderPropertyChanged;
                _destinationDispatcher.Invoke(() => setValue(value), this);
            }

            if (_sourceDispatcher != null)
            {
                _sourceDispatcher.Invoke(readAndSubscribe, this);
            }
            else if (_propertySourceDispatcher != null)
            {
                _propertySourceDispatcher.Invoke(readAndSubscribe, this, true, null);
            }
            else
            {
                readAndSubscribe();
            }
        }
예제 #2
0
        private void initialize(Expression <Func <TResult> > propertyExpression)
        {
            _propertyExpression = propertyExpression;

            MemberExpression memberExpression = (MemberExpression)propertyExpression.Body;

            PropertyInfo      propertyInfo = (PropertyInfo)((MemberExpression)propertyExpression.Body).Member;
            PropertyAccessors propertyAcessors;

            if (!_propertyAccessors.TryGetValue(propertyInfo, out propertyAcessors))
            {
                ParameterExpression valueParameterExpression  = Expression.Parameter(typeof(TResult));
                ParameterExpression holderParameterExpression = Expression.Parameter(typeof(THolder));
                var setter = Expression.Lambda <Action <THolder, TResult> >(
                    Expression.Assign(Expression.Property(holderParameterExpression, propertyInfo), valueParameterExpression),
                    holderParameterExpression, valueParameterExpression).Compile();

                var getter = Expression.Lambda <Func <THolder, TResult> >(
                    Expression.Property(holderParameterExpression, propertyInfo),
                    holderParameterExpression).Compile();

                propertyAcessors = new PropertyAccessors(getter, setter);
                _propertyAccessors.TryAdd(propertyInfo, propertyAcessors);
            }

            _getter = propertyAcessors.Getter;
            _setter = propertyAcessors.Setter;

            _propertyHolder = (THolder)((ConstantExpression)memberExpression.Expression).Value;

            _propertyHolderPropertyChangedEventHandler     = handlePropertyHolderPropertyChanged;
            _propertyHolderWeakPropertyChangedEventHandler =
                new WeakPropertyChangedEventHandler(_propertyHolderPropertyChangedEventHandler);


            void readAndSubscribe()
            {
                getValue();

                void raiseValuePropertyChanged()
                {
                    PropertyChanged?.Invoke(this, Utils.ValuePropertyChangedEventArgs);
                }

                _propertyHolder.PropertyChanged += _propertyHolderWeakPropertyChangedEventHandler.Handle;

                _destinationDispatcher.Invoke(raiseValuePropertyChanged, this);
            }

            if (_sourceDispatcher != null)
            {
                if (_sourceDispatcher != null)
                {
                    _sourceDispatcher.Invoke(readAndSubscribe, this);
                }
                else
                {
                    _propertySourceDispatcher.Invoke(readAndSubscribe, this, true, null);
                }
            }
            else
            {
                readAndSubscribe();
            }

            if (Configuration.SaveInstantiatingStackTrace)
            {
                _instantiatingStackTrace = Environment.StackTrace;
            }
        }