/// <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();
                }
            }
        }
Beispiel #2
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="CompositionContainer"/> class
        ///     with the specified catalog and export providers.
        /// </summary>
        /// <param name="compositionSettings">
        ///     <see cref="CompositionOptions"/> enumeration with flags controlling the composition.
        /// </param>
        /// <param name="providers">
        ///     A <see cref="Array"/> of <see cref="ExportProvider"/> objects which provide
        ///     the <see cref="CompositionContainer"/> access to <see cref="Export"/> objects,
        ///     or <see langword="null"/> to set <see cref="Providers"/> to an empty
        ///     <see cref="ReadOnlyCollection{T}"/>.
        /// </param>
        /// <exception cref="ArgumentException">
        ///     <paramref name="providers"/> contains an element that is <see langword="null"/>.
        /// </exception>
        public CompositionContainer(ComposablePartCatalog catalog, CompositionOptions compositionOptions, params ExportProvider[] providers)
        {
            if (compositionOptions > (CompositionOptions.DisableSilentRejection | CompositionOptions.IsThreadSafe | CompositionOptions.ExportCompositionService))
            {
                throw new ArgumentOutOfRangeException("compositionOptions");
            }
            this._compositionOptions = compositionOptions;

            this._partExportProvider = new ComposablePartExportProvider(compositionOptions);
            this._partExportProvider.SourceProvider = this;

            bool multiProvider = (catalog != null) || providers.Length > 0;

            if (multiProvider)
            {
                if (catalog != null)
                {
                    this._catalogExportProvider = new CatalogExportProvider(catalog, compositionOptions);
                    this._catalogExportProvider.SourceProvider = this;
                    this._localExportProvider = new AggregateExportProvider(this._partExportProvider, this._catalogExportProvider);
                }
                else
                {
                    this._localExportProvider = new AggregateExportProvider(this._partExportProvider);
                }
                if (providers != null && providers.Length > 0)
                {
                    this._ancestorExportProvider = new AggregateExportProvider(providers);
                    this._rootProvider           = new AggregateExportProvider(this._localExportProvider, this._ancestorExportProvider);
                }
                else
                {
                    this._rootProvider = this._localExportProvider;
                }
            }
            else
            {
                this._rootProvider = this._partExportProvider;
            }

            //Insert Composition Service
            if (compositionOptions.HasFlag(CompositionOptions.ExportCompositionService))
            {
                this.ComposeExportedValue <ICompositionService>(new CompositionServiceShim(this));
            }

            this._rootProvider.ExportsChanged  += this.OnExportsChangedInternal;
            this._rootProvider.ExportsChanging += this.OnExportsChangingInternal;

            this._providers = (providers != null) ? new ReadOnlyCollection <ExportProvider>((ExportProvider[])providers.Clone()) : EmptyProviders;
        }
Beispiel #3
0
        public CompositionContainer(ComposablePartCatalog catalog, bool isThreadSafe, params ExportProvider[] providers)
        {
            this._isThreadSafe = isThreadSafe;

            this._partExportProvider = new ComposablePartExportProvider(isThreadSafe);
            this._partExportProvider.SourceProvider = this;

            // the count of all aggregrated providers = 1 (Part EP) + 1 (Catalog EP, if present) + count of given providers;
            int reservedProvidersLength   = 1 + ((catalog != null) ? 1 : 0);
            int aggregatedProvidersLength = reservedProvidersLength + ((providers != null) ? providers.Length : 0);

            if (aggregatedProvidersLength > 1)
            {
                ExportProvider[] aggregatedProviders = new ExportProvider[aggregatedProvidersLength];

                // Add the parts provider
                aggregatedProviders[0] = this._partExportProvider;

                // Add the catalog provider
                if (catalog != null)
                {
                    this._catalogExportProvider = new CatalogExportProvider(catalog, isThreadSafe);
                    this._catalogExportProvider.SourceProvider = this;
                    aggregatedProviders[1] = this._catalogExportProvider;
                }

                // Add the rest of providers
                if ((providers != null) && (providers.Length > 0))
                {
                    Array.Copy(providers, 0, aggregatedProviders, reservedProvidersLength, providers.Length);
                }

                // Create the aggregating provider and if any of the aggregatedProviders is null the constructor will throw an ArgumentExeption
                this._aggregatingExportProvider = new AggregateExportProvider(aggregatedProviders);
                this._rootProvider = this._aggregatingExportProvider;
            }
            else
            {
                Assumes.IsTrue(aggregatedProvidersLength == 1);
                this._rootProvider = this._partExportProvider;
            }

            this._rootProvider.ExportsChanged  += this.OnExportsChangedInternal;
            this._rootProvider.ExportsChanging += this.OnExportsChangingInternal;

            this._providers = (providers != null) ? new ReadOnlyCollection <ExportProvider>((ExportProvider[])providers.Clone()) : EmptyProviders;
        }
Beispiel #4
0
        public CompositionContainer(ComposablePartCatalog catalog, bool isThreadSafe, params ExportProvider[] providers)
        {
            this._importEngine       = new ImportEngine(this, isThreadSafe);
            this._partExportProvider = new ComposablePartExportProvider(isThreadSafe);
            this._partExportProvider.SourceProvider = this;
            this._providers = new ReadOnlyCollection <ExportProvider>(providers != null ? (ExportProvider[])providers.Clone() : new ExportProvider[0]);

            List <ExportProvider> providerList = new List <ExportProvider>();

            providerList.Add(this._partExportProvider);

            if (catalog != null)
            {
                this._catalogExportProvider = new CatalogExportProvider(catalog, isThreadSafe);
                this._catalogExportProvider.SourceProvider = this;

                providerList.Add(this._catalogExportProvider);
            }

            foreach (var provider in this._providers)
            {
                if (provider == null)
                {
                    throw ExceptionBuilder.CreateContainsNullElement("providers");
                }
                providerList.Add(provider);
            }

            // we only build the aggregating provider if necessary - that is, if we have more than one provider to aggregate
            if (providerList.Count > 1)
            {
                this._aggregatingExportProvider = new AggregateExportProvider(providerList);
                this._rootProvider = this._aggregatingExportProvider;
            }
            else
            {
                Assumes.IsTrue(providerList.Count == 1);
                this._rootProvider = providerList[0];
            }

            this._rootProvider.ExportsChanged  += this.OnExportsChangedInternal;
            this._rootProvider.ExportsChanging += this.OnExportsChangingInternal;
        }
Beispiel #5
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="CompositionContainer"/> class
        ///     with the specified catalog and export providers.
        /// </summary>
        /// <param name="compositionSettings">
        ///     <see cref="CompositionOptions"/> enumeration with flags controlling the composition.
        /// </param>
        /// <param name="providers">
        ///     A <see cref="Array"/> of <see cref="ExportProvider"/> objects which provide
        ///     the <see cref="CompositionContainer"/> access to <see cref="Export"/> objects,
        ///     or <see langword="null"/> to set <see cref="Providers"/> to an empty
        ///     <see cref="ReadOnlyCollection{T}"/>.
        /// </param>
        /// <exception cref="ArgumentException">
        ///     <paramref name="providers"/> contains an element that is <see langword="null"/>.
        /// </exception>
        public CompositionContainer(ComposablePartCatalog catalog, CompositionOptions compositionOptions, params ExportProvider[] providers)
        {
            if (compositionOptions > (CompositionOptions.DisableSilentRejection | CompositionOptions.IsThreadSafe | CompositionOptions.ExportCompositionService))
            {
                throw new ArgumentOutOfRangeException("compositionOptions");
            }
            _compositionOptions = compositionOptions;

            // We always create the mutable provider
            _partExportProvider = new ComposablePartExportProvider(compositionOptions);
            _partExportProvider.SourceProvider = this;

            // Create the catalog export provider, only if necessary
            if (catalog != null)
            {
                _catalogExportProvider = new CatalogExportProvider(catalog, compositionOptions);
                _catalogExportProvider.SourceProvider = this;
            }

            // Set the local export provider
            if (_catalogExportProvider != null)
            {
                _localExportProvider           = new AggregateExportProvider(_partExportProvider, _catalogExportProvider);
                _disposableLocalExportProvider = _localExportProvider as IDisposable;
            }
            else
            {
                _localExportProvider = _partExportProvider;
            }

            // Set the ancestor export provider, if ancestors are supplied
            if ((providers != null) && (providers.Length > 0))
            {
                // Aggregate ancestors if and only if more than one passed
                if (providers.Length > 1)
                {
                    _ancestorExportProvider           = new AggregateExportProvider(providers);
                    _disposableAncestorExportProvider = _ancestorExportProvider as IDisposable;
                }
                else
                {
                    if (providers[0] == null)
                    {
                        throw ExceptionBuilder.CreateContainsNullElement("providers");
                    }
                    _ancestorExportProvider = providers[0];
                }
            }

            // finally set the root provider
            if (_ancestorExportProvider == null)
            {
                // if no ancestors are passed, the local and the root are the same
                _rootProvider = _localExportProvider;
            }
            else
            {
                int exportProviderCount        = 1 + ((catalog != null) ? 1 : 0) + ((providers != null) ? providers.Length : 0);
                ExportProvider[] rootProviders = new ExportProvider[exportProviderCount];

                rootProviders[0] = _partExportProvider;
                int customProviderStartIndex = 1;
                if (catalog != null)
                {
                    rootProviders[1]         = _catalogExportProvider;
                    customProviderStartIndex = 2;
                }

                if (providers != null)
                {
                    for (int i = 0; i < providers.Length; i++)
                    {
                        rootProviders[customProviderStartIndex + i] = providers[i];
                    }
                }

                _rootProvider           = new AggregateExportProvider(rootProviders);
                _disposableRootProvider = _rootProvider as IDisposable;
            }

//Insert Composition Service
            if (compositionOptions.HasFlag(CompositionOptions.ExportCompositionService))
            {
                this.ComposeExportedValue <ICompositionService>(new CompositionServiceShim(this));
            }

            _rootProvider.ExportsChanged  += OnExportsChangedInternal;
            _rootProvider.ExportsChanging += OnExportsChangingInternal;

            _providers = (providers != null) ? new ReadOnlyCollection <ExportProvider>((ExportProvider[])providers.Clone()) : EmptyProviders;
        }
Beispiel #6
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();
                    }
                }
            }
        }