Exemple #1
0
        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            this.client.VerifyAccess();
            this.client.VerifyConnected();

            // Check if object is ignored
            if (this.IgnoreChanges)
            {
                return;
            }

            if (!this.IsDynamic && this.IsIgnoredProperty(e.PropertyName))
            {
                return;
            }

            // Check if object is connected
            if (!this.IsConnected)
            {
                throw new InvalidOperationException("Changes cannot be made to this named object until it is connected with the server");
            }

            // Try to extract property information
            SharedProperty property;

            // If dynamic, pull value from dictionary
            object dynamicVal = null;
            if (this.IsDynamic)
            {
                var dictionary = this.Object as IDictionary<string, object>;
                if (!dictionary.TryGetValue(e.PropertyName, out dynamicVal))
                {
                    throw new ArgumentException("Dictionary doesn't contains the value: " + e.PropertyName);
                }
            }
            if (!this.Properties.TryGetValue(e.PropertyName, out property))
            {
                if (this.IsDynamic)
                {
                    // Add new property if dynamic
                    if (dynamicVal != null)
                    {
                        property = new SharedProperty()
                                       {
                                           Attributes = new SharedAttributes(),
                                           Index = -1,
                                           ETag = new ETag(this.client.ClientId),
                                           Name = e.PropertyName,
                                           PropertyType = DynamicTypeMapping.Instance.GetValueFromType(dynamicVal.GetType())
                                       };
                    }
                }
                if (property == null)
                {
                    throw new ArgumentException("Dictionary doesn't contains the value: " + e.PropertyName);
                }
            }
            // Throw exception if property cannot be updated by the client
            if (property.IsServerAppliedProperty())
            {
                 throw new InvalidOperationException("Client cannot modify properties with server-applied attributes");
            }

            // Create payload
            PropertyChangedPayload data = new PropertyChangedPayload(this.client.ClientId, property.Index, this.Id, property.ETag, this.IsDynamic ? dynamicVal : this.Object.GetPropertyValue(e.PropertyName));
            if (this.IsDynamic)
            {
                data.PropertyName = e.PropertyName;
                // Property type might change, we need to re-get each time
                data.PropertyType = DynamicTypeMapping.Instance.GetValueFromType(dynamicVal.GetType());
            }

            // Add to pending update list
            property.LocalUpdates.Add(new PropertyUpdateOperation() { Payload = data, ReapplyUpdate = false });

            // Send to server
            this.client.SendPublishEvent(data);
        }
 public bool IsStudentProgressReportProperty(PropertyChangedPayload<IStudentInformationService> payload)
 {
     return payload.PropertyName == "StudentProgressReport";
 }
        private void UpdateSharedObject(PropertyChangedPayload data)
        {
            Debug.Assert(this.client.CheckAccess());

            ObjectEntry entry = null;

            try
            {
                if (!this.TryGetValue(data.ObjectId, out entry))
                {
                    // Received update for an object we are not tracking
                    Debug.WriteLine("[PropertyChanged] Missing shared object for update in incoming event.");
                    return;
                }

                SharedProperty property = entry.IsDynamic ? entry.Properties[data.PropertyName] : entry.Properties[data.PropertyIndex];

                // In case of dynamic properties, this could be the first time this property is seen
                if (property == null && entry.IsDynamic)
                {
                    property = new SharedProperty()
                    {
                        Attributes   = new SharedAttributes(),
                        Index        = (short)entry.Properties.Count,
                        Name         = data.PropertyName,
                        ETag         = new ETag(this.client.ClientId),
                        PropertyType = data.PropertyType
                    };
                    entry.Properties.Add(property.Index, property);
                }

                // Ignore changes for given object, add to list
                entry.IgnoreChanges = true;

                // Don't apply update if we made it locally
                bool applyUpdate      = data.ClientId != this.client.ClientId;
                bool conflictDetected = false;

                PropertyUpdateOperation matchingUpdate = property.LocalUpdates.Where(x => x.Payload.Equals(data)).FirstOrDefault();
                if (matchingUpdate != null)
                {
                    // Remove update from pending list
                    Debug.WriteLine("[PropertyChanged] Received acknowledgement of matching property update");
                    if (matchingUpdate.ReapplyUpdate)
                    {
                        applyUpdate = true;
                    }
                    property.LocalUpdates.Remove(matchingUpdate);
                }
                // Check for conflict, but won't stop us from applying update
                conflictDetected = data.IsConflict(property.LocalUpdates) &&
                                   !property.IsServerAppliedProperty() && (property.Attributes.ConcurrencyAttribute != ConcurrencyPolicy.Overwrite);

                if (applyUpdate)
                {
                    // Mark pending updates to re-apply if we are applying a change from another endpoint
                    if (data.ClientId != this.client.ClientId)
                    {
                        property.LocalUpdates.ForEach(x => x.ReapplyUpdate = true);
                    }
                    if (entry.IsDynamic)
                    {
                        var dictionary = entry.Object as IDictionary <string, object>;
                        if (dictionary == null)
                        {
                            throw new ArgumentException("Dictionary is null");
                        }

                        // Insert up-to-date value for property
                        dictionary[data.PropertyName] = Json.ReadObject(DynamicTypeMapping.Instance.GetTypeFromValue(data.PropertyType), data.PropertyValue);
                    }
                    else
                    {
                        Json.AssignProperty(entry.Object, property.Name, data.PropertyValue);
                    }
                    property.Value = data.PropertyValue;
                }
                property.ETag = data.ETag;

                if (conflictDetected)
                {
                    Debug.WriteLine("[PropertyChanged] Conflict detected on property update");
                    IEnumerable <PropertyChangedPayload> rejectedUpdates = property.LocalUpdates.Select(x => x.Payload);
                    if (property.Attributes.ConcurrencyAttribute == ConcurrencyPolicy.RejectAndNotify)
                    {
                        var notify = new ConcurrencyUpdateRejectedEventArgs(entry.Object, property.Name, rejectedUpdates.Select(x => Json.ReadProperty(entry.Object, property.Name, x.PropertyValue)));
                        this.client.RaiseError(notify);
                    }
                    property.LocalUpdates.Clear();
                }
            }
            finally
            {
                if (entry != null)
                {
                    entry.IgnoreChanges = false;
                }
            }
        }
 public void StudentProgressReportChanged(PropertyChangedPayload<IStudentInformationService> payload)
 {
     AssignStudentProgressReport(payload.Sender);
 }
Exemple #5
0
        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            this.client.VerifyAccess();
            this.client.VerifyConnected();

            // Check if object is ignored
            if (this.IgnoreChanges)
            {
                return;
            }

            if (!this.IsDynamic && this.IsIgnoredProperty(e.PropertyName))
            {
                return;
            }

            // Check if object is connected
            if (!this.IsConnected)
            {
                throw new InvalidOperationException("Changes cannot be made to this named object until it is connected with the server");
            }

            // Try to extract property information
            SharedProperty property;

            // If dynamic, pull value from dictionary
            object dynamicVal = null;

            if (this.IsDynamic)
            {
                var dictionary = this.Object as IDictionary <string, object>;
                if (!dictionary.TryGetValue(e.PropertyName, out dynamicVal))
                {
                    throw new ArgumentException("Dictionary doesn't contains the value: " + e.PropertyName);
                }
            }
            if (!this.Properties.TryGetValue(e.PropertyName, out property))
            {
                if (this.IsDynamic)
                {
                    // Add new property if dynamic
                    if (dynamicVal != null)
                    {
                        property = new SharedProperty()
                        {
                            Attributes   = new SharedAttributes(),
                            Index        = -1,
                            ETag         = new ETag(this.client.ClientId),
                            Name         = e.PropertyName,
                            PropertyType = DynamicTypeMapping.Instance.GetValueFromType(dynamicVal.GetType())
                        };
                    }
                }
                if (property == null)
                {
                    throw new ArgumentException("Dictionary doesn't contains the value: " + e.PropertyName);
                }
            }
            // Throw exception if property cannot be updated by the client
            if (property.IsServerAppliedProperty())
            {
                throw new InvalidOperationException("Client cannot modify properties with server-applied attributes");
            }

            // Create payload
            PropertyChangedPayload data = new PropertyChangedPayload(this.client.ClientId, property.Index, this.Id, property.ETag, this.IsDynamic ? dynamicVal : this.Object.GetPropertyValue(e.PropertyName));

            if (this.IsDynamic)
            {
                data.PropertyName = e.PropertyName;
                // Property type might change, we need to re-get each time
                data.PropertyType = DynamicTypeMapping.Instance.GetValueFromType(dynamicVal.GetType());
            }

            // Add to pending update list
            property.LocalUpdates.Add(new PropertyUpdateOperation()
            {
                Payload = data, ReapplyUpdate = false
            });

            // Send to server
            this.client.SendPublishEvent(data);
        }