예제 #1
0
        public TValue this[TKey key]
        {
            get
            {
                using (_manager.Lock())
                    return((TValue)_inner[key.ToString()]);
            }
            set
            {
                var property = key.ToString();

                using (_manager.Lock())
                {
                    if (_inner.TryGetValue(property, out var oldValue))
                    {
                        if (value == null)
                        {
                            _manager.ChangeRemove(this, property, oldValue);
                            InternalRemove(property, oldValue);
                        }
                        else
                        {
                            _manager.ChangeReplace(this, property, value, oldValue);
                            InternalReplace(property, oldValue, value);
                        }
                    }
                    else
                    {
                        if (value != null)
                        {
                            _manager.ChangeAdd(this, property, value);
                            InternalAdd(property, value);
                        }
                    }
                }
            }
        }
        public void Intercept(IInvocation invocation)
        {
            var name = invocation.Method.Name;

            if (name == nameof(IEntityHandlerProvider.GetHandler))
            {
                invocation.ReturnValue = this;
            }
            else if (name.StartsWith("get_"))
            {
                using (_manager.Lock())
                {
                    var property = name.Substring(4);

                    if (property == nameof(ILocalHolder.Local))
                    {
                        invocation.ReturnValue = _local;
                    }
                    else
                    {
                        if (!_values.TryGetValue(property, out var entry))
                        {
                            entry = _typeConfig.Members[property].TypeConfiguration.DefaultValue;
                        }

                        invocation.ReturnValue = entry;
                    }
                }
            }
            else if (name.StartsWith("set_"))
            {
                var property = name.Substring(4);

                using (_manager.Lock())
                {
                    var newValue     = invocation.Arguments[0];
                    var memberConfig = _typeConfig.Members[property];

                    if (!_values.TryGetValue(property, out var value))
                    {
                        if (newValue != null)
                        {
                            // null => value
                            _values[property] = newValue;
                            _manager.ChangeAdd(this, property, newValue);
                        }
                        //else null => null
                    }
                    else
                    {
                        if (newValue == null)
                        {
                            // value => null
                            _values.Remove(property);
                            _manager.ChangeRemove(this, property, value);
                        }
                        else
                        {
                            //value => value
                            if (memberConfig.DontCompareBeforeSet || !Equals(value, newValue))
                            {
                                _values[property] = newValue;
                                _manager.ChangeReplace(this, property, newValue, value);
                            }
                        }
                    }
                }
                _propertyChangedHandler?.Invoke(invocation.Proxy, new PropertyChangedEventArgs(property));
            }
            else if (invocation.Method.Name == "add_PropertyChanged")
            {
                _propertyChangedHandler = (PropertyChangedEventHandler)Delegate.Combine(_propertyChangedHandler, (Delegate)invocation.Arguments[0]);
            }
            else if (invocation.Method.Name == "remove_PropertyChanged")
            {
                _propertyChangedHandler = (PropertyChangedEventHandler)Delegate.Remove(_propertyChangedHandler, (Delegate)invocation.Arguments[0]);
            }
        }