Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Objects / ObjectViewListener.cs / 1 / 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
- RijndaelManaged.cs
- PageTheme.cs
- DataGridViewImageCell.cs
- ListBox.cs
- PrimitiveSchema.cs
- PropertyManager.cs
- SecureUICommand.cs
- TryLoadRunnableWorkflowCommand.cs
- RayHitTestParameters.cs
- HttpPostedFile.cs
- DispatcherSynchronizationContext.cs
- TiffBitmapDecoder.cs
- SoapSchemaMember.cs
- Vector3dCollection.cs
- SaveFileDialog.cs
- CookieProtection.cs
- InstanceCreationEditor.cs
- NamedElement.cs
- HttpCookieCollection.cs
- CategoryEditor.cs
- ConsumerConnectionPoint.cs
- XmlEncodedRawTextWriter.cs
- SelectionRangeConverter.cs
- SpeechUI.cs
- Debug.cs
- XmlCollation.cs
- SynthesizerStateChangedEventArgs.cs
- BindStream.cs
- PassportPrincipal.cs
- SqlBulkCopyColumnMappingCollection.cs
- NullableLongMinMaxAggregationOperator.cs
- SetStateDesigner.cs
- DecoratedNameAttribute.cs
- BinaryParser.cs
- InputLangChangeRequestEvent.cs
- EdmRelationshipRoleAttribute.cs
- FlowDocumentFormatter.cs
- ClassData.cs
- AddInSegmentDirectoryNotFoundException.cs
- ServiceMemoryGates.cs
- SqlInternalConnection.cs
- ResourcesChangeInfo.cs
- MimeFormReflector.cs
- AdapterDictionary.cs
- HelloMessage11.cs
- EntityReference.cs
- SystemIcmpV4Statistics.cs
- ConnectionManagementElementCollection.cs
- AudioDeviceOut.cs
- UnmanagedMemoryStreamWrapper.cs
- ListViewTableCell.cs
- IPAddress.cs
- File.cs
- RichTextBox.cs
- Suspend.cs
- MILUtilities.cs
- GeneratedContractType.cs
- WebServicesSection.cs
- WindowsTreeView.cs
- StyleXamlTreeBuilder.cs
- PauseStoryboard.cs
- sortedlist.cs
- RuntimeIdentifierPropertyAttribute.cs
- BooleanStorage.cs
- DataBindingCollectionEditor.cs
- DynamicVirtualDiscoSearcher.cs
- ExpressionBuilderContext.cs
- WindowCollection.cs
- Visual3D.cs
- ConstNode.cs
- PhonemeConverter.cs
- RoutedEventConverter.cs
- EventsTab.cs
- SchemaNotation.cs
- CodeEventReferenceExpression.cs
- BamlLocalizabilityResolver.cs
- AspNetSynchronizationContext.cs
- ObjectPersistData.cs
- ChtmlSelectionListAdapter.cs
- ProviderException.cs
- DependencyProperty.cs
- _AutoWebProxyScriptEngine.cs
- AppliedDeviceFiltersEditor.cs
- ConcurrentQueue.cs
- XmlAtomicValue.cs
- WebServicesDescriptionAttribute.cs
- WindowsRichEdit.cs
- Animatable.cs
- CustomError.cs
- PropertyMetadata.cs
- DataColumnPropertyDescriptor.cs
- BinaryFormatterSinks.cs
- Assembly.cs
- SafeProcessHandle.cs
- BackStopAuthenticationModule.cs
- TransportReplyChannelAcceptor.cs
- XPathAncestorQuery.cs
- RenderTargetBitmap.cs
- InvokeBinder.cs
- EntityCollection.cs