Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / 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
- Security.cs
- CharStorage.cs
- SecurityTokenException.cs
- Menu.cs
- ContentPlaceHolderDesigner.cs
- ApplyImportsAction.cs
- RecordBuilder.cs
- prefixendpointaddressmessagefilter.cs
- KoreanCalendar.cs
- WebPartVerb.cs
- WSTrust.cs
- UdpChannelListener.cs
- TableCell.cs
- WindowsFormsHostAutomationPeer.cs
- DbConnectionPoolCounters.cs
- PolygonHotSpot.cs
- ReachPrintTicketSerializer.cs
- WebEncodingValidator.cs
- XmlDataImplementation.cs
- BlurEffect.cs
- EditorPart.cs
- ThicknessAnimationUsingKeyFrames.cs
- MULTI_QI.cs
- KeyGestureConverter.cs
- WebPartCancelEventArgs.cs
- RuntimeUtils.cs
- XmlAttribute.cs
- DecoderFallback.cs
- LabelLiteral.cs
- InvokePatternIdentifiers.cs
- DataGridViewCellPaintingEventArgs.cs
- DrawingContextDrawingContextWalker.cs
- PanelStyle.cs
- PingOptions.cs
- ClassValidator.cs
- XmlSchemaObjectTable.cs
- OdbcCommand.cs
- PolyLineSegment.cs
- XmlSchemaSubstitutionGroup.cs
- BroadcastEventHelper.cs
- InheritablePropertyChangeInfo.cs
- ExtenderProvidedPropertyAttribute.cs
- ClientSettingsStore.cs
- PropertyToken.cs
- ContextBase.cs
- AuthenticationSection.cs
- EntityViewGenerationAttribute.cs
- PreservationFileWriter.cs
- TextBounds.cs
- SiteMapHierarchicalDataSourceView.cs
- Process.cs
- XsltArgumentList.cs
- RootProfilePropertySettingsCollection.cs
- ConfigurationElement.cs
- MultipleViewPatternIdentifiers.cs
- GridViewRow.cs
- SemaphoreFullException.cs
- TypeSystem.cs
- ClientSettingsSection.cs
- AlphabeticalEnumConverter.cs
- CompoundFileDeflateTransform.cs
- FixedDocumentPaginator.cs
- TimeBoundedCache.cs
- WebSysDisplayNameAttribute.cs
- InternalRelationshipCollection.cs
- XpsStructure.cs
- TableRowCollection.cs
- NullableIntMinMaxAggregationOperator.cs
- CacheRequest.cs
- IxmlLineInfo.cs
- ChtmlLinkAdapter.cs
- VariableAction.cs
- SignatureDescription.cs
- SHA512Cng.cs
- SizeKeyFrameCollection.cs
- CompletionBookmark.cs
- AssemblyLoader.cs
- LayoutTableCell.cs
- HashHelper.cs
- FilterRepeater.cs
- SystemIcmpV4Statistics.cs
- ErasingStroke.cs
- AddInController.cs
- SizeKeyFrameCollection.cs
- SqlResolver.cs
- ScriptResourceAttribute.cs
- SerializableReadOnlyDictionary.cs
- XmlSchemaSimpleTypeRestriction.cs
- AnnotationMap.cs
- GridItemPattern.cs
- XPathAncestorQuery.cs
- CodeNamespace.cs
- ResourceReader.cs
- ContextDataSourceView.cs
- ChannelProtectionRequirements.cs
- CalendarKeyboardHelper.cs
- BlockUIContainer.cs
- XmlEntityReference.cs
- AlphabeticalEnumConverter.cs
- M3DUtil.cs