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
- WSSecurityOneDotOneReceiveSecurityHeader.cs
- BindingNavigatorDesigner.cs
- AnimatedTypeHelpers.cs
- RewritingProcessor.cs
- IIS7WorkerRequest.cs
- NamedObject.cs
- DropShadowBitmapEffect.cs
- SafeNativeMethods.cs
- AccessDataSourceView.cs
- Typeface.cs
- TableLayoutCellPaintEventArgs.cs
- View.cs
- ProfilePropertySettingsCollection.cs
- DataRowCollection.cs
- IERequestCache.cs
- PeerNameRecordCollection.cs
- PerspectiveCamera.cs
- ParenthesizePropertyNameAttribute.cs
- TextureBrush.cs
- PageCodeDomTreeGenerator.cs
- FactoryGenerator.cs
- WebServiceFault.cs
- DynamicUpdateCommand.cs
- ScriptResourceHandler.cs
- DataGridCaption.cs
- HttpCachePolicyWrapper.cs
- UnsafeNativeMethods.cs
- SqlFormatter.cs
- ValidationVisibilityAttribute.cs
- EntityDataSourceEntityTypeFilterConverter.cs
- FixedSOMTableRow.cs
- CuspData.cs
- RowBinding.cs
- DataColumnMapping.cs
- PresentationTraceSources.cs
- FixedTextContainer.cs
- SecurityDocument.cs
- StaticResourceExtension.cs
- Help.cs
- ResXFileRef.cs
- XmlImplementation.cs
- SpellerHighlightLayer.cs
- CustomPeerResolverService.cs
- NamespaceQuery.cs
- DbException.cs
- DiscoveryDocumentLinksPattern.cs
- UserValidatedEventArgs.cs
- DesignerCategoryAttribute.cs
- ReaderWriterLockSlim.cs
- Lease.cs
- ThreadStartException.cs
- DefaultEventAttribute.cs
- ResponseStream.cs
- DataServiceConfiguration.cs
- RootBuilder.cs
- DataGridViewTextBoxColumn.cs
- ExpandSegmentCollection.cs
- ToggleProviderWrapper.cs
- ImageBrush.cs
- RootProfilePropertySettingsCollection.cs
- Compensate.cs
- PrinterUnitConvert.cs
- storepermissionattribute.cs
- Italic.cs
- DesignerUtility.cs
- PropertyInformationCollection.cs
- ReachDocumentReferenceSerializer.cs
- ProviderConnectionPointCollection.cs
- ValidationResult.cs
- Task.cs
- CodeNamespaceImport.cs
- Brush.cs
- StylusPlugin.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- ClientUriBehavior.cs
- SqlDataSourceQueryEditorForm.cs
- DurableDispatcherAddressingFault.cs
- ConstructorArgumentAttribute.cs
- XmlNamedNodeMap.cs
- NativeMethodsOther.cs
- CompositeControl.cs
- DataGridViewCellStateChangedEventArgs.cs
- WebPartManagerInternals.cs
- TextClipboardData.cs
- WebProxyScriptElement.cs
- FastEncoderWindow.cs
- FileEnumerator.cs
- XsltLibrary.cs
- SmtpNegotiateAuthenticationModule.cs
- EdmConstants.cs
- TemplateXamlTreeBuilder.cs
- cookiecontainer.cs
- CharAnimationBase.cs
- DrawingGroupDrawingContext.cs
- TextSelectionProcessor.cs
- XsltCompileContext.cs
- WrappedIUnknown.cs
- GlyphRun.cs
- ContentType.cs
- RpcAsyncResult.cs