/// <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();
                }
            }
        }
Example #2
0
        /// <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);
        }
Example #5
0
        /// <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();
                            }
                        }
                    }
                }
            }
        }
Example #7
0
        /// <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();
                        }
                    }
                }
            }
        }