Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Objects / ObjectViewListener.cs / 2 / ObjectViewListener.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data.Objects.DataClasses; using System.Diagnostics; // Dev notes -1 // why we need this class: in order to keep the view alive, we have to listen to evens from entities and // also EntityCollection/ObjectStateManager they exists in. listening to event will prevent the view to be // disposed, hence GC'ed due to having a strong reference; and to avoid this situation we have to introduce // a new layer which will have a weakreference to view (1-so it can go out of scope, 2- this layer will listen to // the events and notify the view - by calling its APIS- for any change that happens) // Dev notes -2 // following statement is valid on current existing CLR: // lets say Customer is an Entity, Array[Customer] is not Array[Entity]; it is not supported // to do the work around we have to use a non-Generic interface/class so we can pass the view // to ObjectViewListener safely (IObjectView) namespace System.Data.Objects { internal sealed class ObjectViewListener { private WeakReference _viewWeak; private object _dataSource; private IList _list; internal ObjectViewListener(IObjectView view, IList list, object dataSource) { _viewWeak = new WeakReference(view); _dataSource = dataSource; _list = list; RegisterCollectionEvents(); RegisterEntityEvents(); } private void CleanUpListener() { UnregisterCollectionEvents(); UnregisterEntityEvents(); } private void RegisterCollectionEvents() { ObjectStateManager cache = _dataSource as ObjectStateManager; if (cache != null) { cache.EntityDeleted += CollectionChanged; } else if (null != _dataSource) { ((RelatedEnd)_dataSource).AssociationChangedForObjectView += CollectionChanged; } } private void UnregisterCollectionEvents() { ObjectStateManager cache = _dataSource as ObjectStateManager; if (cache != null) { cache.EntityDeleted -= CollectionChanged; } else if (null != _dataSource) { ((RelatedEnd)_dataSource).AssociationChangedForObjectView -= CollectionChanged; } } internal void RegisterEntityEvents(object entity) { Debug.Assert(entity != null, "Entity should not be null"); INotifyPropertyChanged propChanged = entity as INotifyPropertyChanged; if (propChanged != null) { propChanged.PropertyChanged += EntityPropertyChanged; } } private void RegisterEntityEvents() { if (null != _list) { foreach (object entityObject in _list) { IEntityWithChangeTracker entity = entityObject as IEntityWithChangeTracker; //POCO will relax this requirement if (entity != null) { INotifyPropertyChanged propChanged = entity as INotifyPropertyChanged; if (propChanged != null) { propChanged.PropertyChanged += EntityPropertyChanged; } } } } } internal void UnregisterEntityEvents(object entity) { Debug.Assert(entity != null, "entity should not be null"); INotifyPropertyChanged propChanged = entity as INotifyPropertyChanged; if (propChanged != null) { propChanged.PropertyChanged -= EntityPropertyChanged; } } private void UnregisterEntityEvents() { if (null != _list) { foreach (object entityObject in _list) { IEntityWithChangeTracker entity = entityObject as IEntityWithChangeTracker; //POCO will relax this requirement. if (entity != null) { INotifyPropertyChanged propChanged = entity as INotifyPropertyChanged; if (propChanged != null) { propChanged.PropertyChanged -= EntityPropertyChanged; } } } } } private void EntityPropertyChanged(object sender, PropertyChangedEventArgs e) { IObjectView view = (IObjectView)_viewWeak.Target; if (view != null) { view.EntityPropertyChanged(sender, e); } else { CleanUpListener(); } } private void CollectionChanged(object sender, CollectionChangeEventArgs e) { IObjectView view = (IObjectView)_viewWeak.Target; if (view != null) { view.CollectionChanged(sender, e); } else { CleanUpListener(); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data.Objects.DataClasses; using System.Diagnostics; // Dev notes -1 // why we need this class: in order to keep the view alive, we have to listen to evens from entities and // also EntityCollection/ObjectStateManager they exists in. listening to event will prevent the view to be // disposed, hence GC'ed due to having a strong reference; and to avoid this situation we have to introduce // a new layer which will have a weakreference to view (1-so it can go out of scope, 2- this layer will listen to // the events and notify the view - by calling its APIS- for any change that happens) // Dev notes -2 // following statement is valid on current existing CLR: // lets say Customer is an Entity, Array[Customer] is not Array[Entity]; it is not supported // to do the work around we have to use a non-Generic interface/class so we can pass the view // to ObjectViewListener safely (IObjectView) namespace System.Data.Objects { internal sealed class ObjectViewListener { private WeakReference _viewWeak; private object _dataSource; private IList _list; internal ObjectViewListener(IObjectView view, IList list, object dataSource) { _viewWeak = new WeakReference(view); _dataSource = dataSource; _list = list; RegisterCollectionEvents(); RegisterEntityEvents(); } private void CleanUpListener() { UnregisterCollectionEvents(); UnregisterEntityEvents(); } private void RegisterCollectionEvents() { ObjectStateManager cache = _dataSource as ObjectStateManager; if (cache != null) { cache.EntityDeleted += CollectionChanged; } else if (null != _dataSource) { ((RelatedEnd)_dataSource).AssociationChangedForObjectView += CollectionChanged; } } private void UnregisterCollectionEvents() { ObjectStateManager cache = _dataSource as ObjectStateManager; if (cache != null) { cache.EntityDeleted -= CollectionChanged; } else if (null != _dataSource) { ((RelatedEnd)_dataSource).AssociationChangedForObjectView -= CollectionChanged; } } internal void RegisterEntityEvents(object entity) { Debug.Assert(entity != null, "Entity should not be null"); INotifyPropertyChanged propChanged = entity as INotifyPropertyChanged; if (propChanged != null) { propChanged.PropertyChanged += EntityPropertyChanged; } } private void RegisterEntityEvents() { if (null != _list) { foreach (object entityObject in _list) { IEntityWithChangeTracker entity = entityObject as IEntityWithChangeTracker; //POCO will relax this requirement if (entity != null) { INotifyPropertyChanged propChanged = entity as INotifyPropertyChanged; if (propChanged != null) { propChanged.PropertyChanged += EntityPropertyChanged; } } } } } internal void UnregisterEntityEvents(object entity) { Debug.Assert(entity != null, "entity should not be null"); INotifyPropertyChanged propChanged = entity as INotifyPropertyChanged; if (propChanged != null) { propChanged.PropertyChanged -= EntityPropertyChanged; } } private void UnregisterEntityEvents() { if (null != _list) { foreach (object entityObject in _list) { IEntityWithChangeTracker entity = entityObject as IEntityWithChangeTracker; //POCO will relax this requirement. if (entity != null) { INotifyPropertyChanged propChanged = entity as INotifyPropertyChanged; if (propChanged != null) { propChanged.PropertyChanged -= EntityPropertyChanged; } } } } } private void EntityPropertyChanged(object sender, PropertyChangedEventArgs e) { IObjectView view = (IObjectView)_viewWeak.Target; if (view != null) { view.EntityPropertyChanged(sender, e); } else { CleanUpListener(); } } private void CollectionChanged(object sender, CollectionChangeEventArgs e) { IObjectView view = (IObjectView)_viewWeak.Target; if (view != null) { view.CollectionChanged(sender, e); } else { CleanUpListener(); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MulticastOption.cs
- CodeDirectionExpression.cs
- HttpResponseMessageProperty.cs
- DebugInfoExpression.cs
- OutputCacheSection.cs
- ReadingWritingEntityEventArgs.cs
- ProfileSettings.cs
- WebServiceParameterData.cs
- WebUtil.cs
- CSharpCodeProvider.cs
- XmlHierarchicalDataSourceView.cs
- WebResponse.cs
- ListCardsInFileRequest.cs
- SystemNetworkInterface.cs
- OracleCommandSet.cs
- Single.cs
- HitTestWithGeometryDrawingContextWalker.cs
- Substitution.cs
- OdbcParameterCollection.cs
- SignatureHelper.cs
- _ListenerRequestStream.cs
- KeyboardEventArgs.cs
- Control.cs
- ImageSource.cs
- SQLBinary.cs
- SqlDuplicator.cs
- RawUIStateInputReport.cs
- Run.cs
- DocumentsTrace.cs
- SamlSerializer.cs
- WpfPayload.cs
- LogPolicy.cs
- CommandManager.cs
- AssemblyBuilder.cs
- ScaleTransform.cs
- ServiceReference.cs
- MimeFormReflector.cs
- assertwrapper.cs
- GeneralTransformCollection.cs
- SerialPort.cs
- ModuleBuilderData.cs
- _SslState.cs
- LeaseManager.cs
- BamlResourceDeserializer.cs
- WindowCollection.cs
- SystemInfo.cs
- PropertyInformation.cs
- RequestQueue.cs
- LockCookie.cs
- ProfilePropertySettings.cs
- CultureSpecificCharacterBufferRange.cs
- SessionPageStateSection.cs
- GroupBox.cs
- Stroke.cs
- ButtonFieldBase.cs
- FlatButtonAppearance.cs
- ByteStreamGeometryContext.cs
- MailMessageEventArgs.cs
- TextDecoration.cs
- HandlerMappingMemo.cs
- DataConnectionHelper.cs
- HyperLinkColumn.cs
- CompositeTypefaceMetrics.cs
- TextEmbeddedObject.cs
- compensatingcollection.cs
- StatusStrip.cs
- TableItemProviderWrapper.cs
- Vector3DCollection.cs
- SettingsAttributeDictionary.cs
- ImageCodecInfo.cs
- StrokeRenderer.cs
- XmlEventCache.cs
- XmlSchemaGroupRef.cs
- XmlSchemaExporter.cs
- VolatileEnlistmentMultiplexing.cs
- ExpressionParser.cs
- CharacterBuffer.cs
- Line.cs
- DiscreteKeyFrames.cs
- PersistChildrenAttribute.cs
- SendSecurityHeaderElementContainer.cs
- LocatorManager.cs
- MetadataItemEmitter.cs
- WebPartVerbsEventArgs.cs
- XmlCharCheckingReader.cs
- TextPattern.cs
- PropertyState.cs
- JsonFormatGeneratorStatics.cs
- TextRangeEdit.cs
- Matrix3DValueSerializer.cs
- AnimationTimeline.cs
- CaseInsensitiveOrdinalStringComparer.cs
- TextEditorCharacters.cs
- DataGridViewColumnStateChangedEventArgs.cs
- SafeRightsManagementQueryHandle.cs
- NavigationPropertySingletonExpression.cs
- SoundPlayerAction.cs
- XmlWriterTraceListener.cs
- UnicastIPAddressInformationCollection.cs
- InlinedAggregationOperatorEnumerator.cs