/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (disposing) { if (!_isDisposed) { ExportProvider?rootProvider = null; IDisposable? disposableAncestorExportProvider = null; IDisposable? disposableLocalExportProvider = null; IDisposable? disposableRootProvider = null; ComposablePartExportProvider?partExportProvider = null; CatalogExportProvider? catalogExportProvider = null; ImportEngine?importEngine = null; lock (_lock) { if (!_isDisposed) { rootProvider = _rootProvider; _rootProvider = null !; disposableRootProvider = _disposableRootProvider; _disposableRootProvider = null; disposableLocalExportProvider = _disposableLocalExportProvider; _disposableLocalExportProvider = null; _localExportProvider = null !; disposableAncestorExportProvider = _disposableAncestorExportProvider; _disposableAncestorExportProvider = null; _ancestorExportProvider = null; partExportProvider = _partExportProvider; _partExportProvider = null !; catalogExportProvider = _catalogExportProvider; _catalogExportProvider = null; importEngine = _importEngine; _importEngine = null; _isDisposed = true; } } if (rootProvider != null) { rootProvider.ExportsChanged -= OnExportsChangedInternal; rootProvider.ExportsChanging -= OnExportsChangingInternal; } disposableRootProvider?.Dispose(); disposableAncestorExportProvider?.Dispose(); disposableLocalExportProvider?.Dispose(); catalogExportProvider?.Dispose(); partExportProvider?.Dispose(); importEngine?.Dispose(); } } }
/// <summary> /// Sets the imports of the specified composable part exactly once and they will not /// ever be recomposed. /// </summary> /// <param name="part"> /// The <see cref="ComposablePart"/> to set the imports. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="part"/> is <see langword="null"/>. /// </exception> /// <exception cref="CompositionException"> /// An error occurred during composition. <see cref="CompositionException.Errors"/> will /// contain a collection of errors that occurred. /// </exception> /// <exception cref="ObjectDisposedException"> /// The <see cref="ICompositionService"/> has been disposed of. /// </exception> public void SatisfyImportsOnce(ComposablePart part) { this.ThrowIfDisposed(); if (this._importEngine == null) { ImportEngine importEngine = new ImportEngine(this, this._isThreadSafe); lock (this._lock) { if (this._importEngine == null) { Thread.MemoryBarrier(); this._importEngine = importEngine; importEngine = null; } } if (importEngine != null) { importEngine.Dispose(); } } this._importEngine.SatisfyImportsOnce(part); }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (disposing) { if (!_isDisposed) { bool disposeLock = false; ImportEngine?importEngine = null; try { using (_lock.LockStateForWrite()) { if (!_isDisposed) { importEngine = _importEngine; _importEngine = null; _sourceProvider = null; _isDisposed = true; disposeLock = true; } } } finally { importEngine?.Dispose(); if (disposeLock) { _lock.Dispose(); } } } } }
/// <summary> /// Sets the imports of the specified composable part exactly once and they will not /// ever be recomposed. /// </summary> /// <param name="part"> /// The <see cref="ComposablePart"/> to set the imports. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="part"/> is <see langword="null"/>. /// </exception> /// <exception cref="CompositionException"> /// An error occurred during composition. <see cref="CompositionException.Errors"/> will /// contain a collection of errors that occurred. /// </exception> /// <exception cref="ObjectDisposedException"> /// The <see cref="ICompositionService"/> has been disposed of. /// </exception> public void SatisfyImportsOnce(ComposablePart part) { ThrowIfDisposed(); if (_importEngine == null) { ImportEngine?importEngine = new ImportEngine(this, _compositionOptions); lock (_lock) { if (_importEngine == null) { Thread.MemoryBarrier(); _importEngine = importEngine; importEngine = null; } } importEngine?.Dispose(); } _importEngine.SatisfyImportsOnce(part); }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (disposing) { if (!this._isDisposed) { bool disposeLock = false; ImportEngine importEngine = null; try { using (this._lock.LockStateForWrite()) { if (!this._isDisposed) { importEngine = this._importEngine; this._importEngine = null; this._sourceProvider = null; this._isDisposed = true; disposeLock = true; } } } finally { if (importEngine != null) { importEngine.Dispose(); } if (disposeLock) { this._lock.Dispose(); } } } } }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (disposing) { if (!_isDisposed) { //Note: We do not dispose _lock on dispose because DisposePart needs it to check isDisposed state // to eliminate race conditions between it and Dispose INotifyComposablePartCatalogChanged catalogToUnsubscribeFrom = null; HashSet <IDisposable> partsToDispose = null; ImportEngine importEngine = null; ExportProvider sourceProvider = null; AggregateExportProvider aggregateExportProvider = null; try { using (_lock.LockStateForWrite()) { if (!_isDisposed) { catalogToUnsubscribeFrom = _catalog as INotifyComposablePartCatalogChanged; _catalog = null; aggregateExportProvider = _innerExportProvider as AggregateExportProvider; _innerExportProvider = null; sourceProvider = _sourceProvider; _sourceProvider = null; importEngine = _importEngine; _importEngine = null; partsToDispose = _partsToDispose; _gcRoots = null; _isDisposed = true; } } } finally { if (catalogToUnsubscribeFrom != null) { catalogToUnsubscribeFrom.Changing -= OnCatalogChanging; } if (aggregateExportProvider != null) { aggregateExportProvider.Dispose(); } if (sourceProvider != null) { sourceProvider.ExportsChanging -= OnExportsChangingInternal; } if (importEngine != null) { importEngine.Dispose(); } if (partsToDispose != null) { foreach (var part in partsToDispose) { part.Dispose(); } } } } } }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (disposing) { if (!this._isDisposed) { ExportProvider rootProvider = null; AggregateExportProvider aggregatingExportProvider = null; ComposablePartExportProvider partExportProvider = null; CatalogExportProvider catalogExportProvider = null; ImportEngine importEngine = null; lock (this._lock) { if (!this._isDisposed) { rootProvider = this._rootProvider; this._rootProvider = null; aggregatingExportProvider = this._aggregatingExportProvider; this._aggregatingExportProvider = null; partExportProvider = this._partExportProvider; this._partExportProvider = null; catalogExportProvider = this._catalogExportProvider; this._catalogExportProvider = null; importEngine = this._importEngine; this._importEngine = null; this._isDisposed = true; } } if (rootProvider != null) { rootProvider.ExportsChanged -= this.OnExportsChangedInternal; rootProvider.ExportsChanging -= this.OnExportsChangingInternal; } if (aggregatingExportProvider != null) { aggregatingExportProvider.Dispose(); } if (catalogExportProvider != null) { catalogExportProvider.Dispose(); } if (partExportProvider != null) { partExportProvider.Dispose(); } if (importEngine != null) { importEngine.Dispose(); } } } }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (disposing) { if (!this._isDisposed) { bool disposeLock = false; INotifyComposablePartCatalogChanged catalogToUnsubscribeFrom = null; HashSet <IDisposable> partsToDispose = null; ImportEngine importEngine = null; ExportProvider sourceProvider = null; try { using (this._lock.LockStateForWrite()) { if (!this._isDisposed) { catalogToUnsubscribeFrom = this._catalog as INotifyComposablePartCatalogChanged; this._catalog = null; sourceProvider = this._sourceProvider; this._sourceProvider = null; importEngine = this._importEngine; this._importEngine = null; partsToDispose = this._partsToDispose; this._gcRoots = null; disposeLock = true; this._isDisposed = true; } } } finally { if (catalogToUnsubscribeFrom != null) { catalogToUnsubscribeFrom.Changing -= this.OnCatalogChanging; } if (sourceProvider != null) { sourceProvider.ExportsChanging -= this.OnExportsChangingInternal; } if (importEngine != null) { importEngine.Dispose(); } if (partsToDispose != null) { foreach (var part in partsToDispose) { part.Dispose(); } } if (disposeLock) { this._lock.Dispose(); } } } } }