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
- SqlServer2KCompatibilityCheck.cs
- XhtmlBasicCommandAdapter.cs
- HeaderedContentControl.cs
- HandleCollector.cs
- SapiAttributeParser.cs
- UserValidatedEventArgs.cs
- SerTrace.cs
- Int32CAMarshaler.cs
- XamlStream.cs
- WebPartAddingEventArgs.cs
- ILGenerator.cs
- ImageListStreamer.cs
- CallbackValidatorAttribute.cs
- EllipticalNodeOperations.cs
- ShaperBuffers.cs
- SessionEndedEventArgs.cs
- Metafile.cs
- PointCollection.cs
- unsafenativemethodsother.cs
- VirtualizingPanel.cs
- RSAPKCS1SignatureDeformatter.cs
- HealthMonitoringSectionHelper.cs
- ResourceDescriptionAttribute.cs
- WmiEventSink.cs
- AvTraceFormat.cs
- ChannelHandler.cs
- ApplicationGesture.cs
- CodeMemberEvent.cs
- AccessDataSourceView.cs
- FrugalMap.cs
- Constants.cs
- RelationshipConstraintValidator.cs
- DefaultTextStoreTextComposition.cs
- DES.cs
- Pen.cs
- DetailsViewDesigner.cs
- TrackingProfileSerializer.cs
- FixedDSBuilder.cs
- DiagnosticStrings.cs
- TemplatedMailWebEventProvider.cs
- CriticalFinalizerObject.cs
- VersionedStream.cs
- XmlSchemaType.cs
- DictionaryContent.cs
- XmlToDatasetMap.cs
- InvalidWorkflowException.cs
- CheckBox.cs
- DateBoldEvent.cs
- SR.Designer.cs
- ThrowOnMultipleAssignment.cs
- IsolatedStorageException.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- HMACSHA256.cs
- OpCodes.cs
- UInt64Storage.cs
- SmtpSection.cs
- SmiRecordBuffer.cs
- VideoDrawing.cs
- SchemaElementDecl.cs
- PathSegmentCollection.cs
- TextViewBase.cs
- WebServiceClientProxyGenerator.cs
- DataGridViewAdvancedBorderStyle.cs
- SoapObjectInfo.cs
- DelegateTypeInfo.cs
- BooleanAnimationUsingKeyFrames.cs
- CapiSymmetricAlgorithm.cs
- BindingParameterCollection.cs
- DataGridView.cs
- ProxyFragment.cs
- ZipIOLocalFileBlock.cs
- SourceExpressionException.cs
- WindowsFormsSynchronizationContext.cs
- ReferencedType.cs
- XmlWriter.cs
- DateTimePicker.cs
- PageAdapter.cs
- XomlCompiler.cs
- HwndPanningFeedback.cs
- ProtectedConfigurationProviderCollection.cs
- WizardPanel.cs
- X509SubjectKeyIdentifierClause.cs
- XmlSchemaSimpleContentRestriction.cs
- SmtpCommands.cs
- Pipe.cs
- XmlExtensionFunction.cs
- SecurityRequiresReviewAttribute.cs
- CompositeActivityTypeDescriptor.cs
- WorkflowLayouts.cs
- DataSetUtil.cs
- ServiceBuildProvider.cs
- EntityKeyElement.cs
- ProfileServiceManager.cs
- ReadOnlyDataSource.cs
- FilteredXmlReader.cs
- CompilerTypeWithParams.cs
- TextRange.cs
- BatchStream.cs
- TypeExtensionSerializer.cs
- ToolBarOverflowPanel.cs