public void Constructor2_ArrayAsProvidersArgument_ShouldNotAllowModificationAfterConstruction()
        {
            var providers = new ExportProvider[] { ExportProviderFactory.Create() };
            var provider = new AggregateExportProvider((IEnumerable<ExportProvider>)providers);

            providers[0] = null;

            Assert.IsNotNull(provider.Providers[0]);
        }
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;
        }
        public void CanBeCollectedAfterDispose()
        {
            AggregateExportProvider exportProvider = new AggregateExportProvider();
            var catalog = new AggregateCatalog(CatalogFactory.CreateDefaultAttributed());
            var container = new CompositionContainer(catalog, exportProvider);

            WeakReference weakContainer = new WeakReference(container);
            container.Dispose();
            container = null;

            GC.Collect();
            GC.WaitForPendingFinalizers();

            Assert.IsFalse(weakContainer.IsAlive);

            GC.KeepAlive(exportProvider);
            GC.KeepAlive(catalog);
        }
Beispiel #5
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;
        }
        /// <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();
                            }
                        }
                    }
                }
            }
        }
Beispiel #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();
                    }
                }
            }
        }
        public void Constructor2_EmptyEnumerableAsProvidersArgument_ShouldSetProvidersPropertyToEmpty()
        {
            var provider = new AggregateExportProvider(Enumerable.Empty<ExportProvider>());

            EnumerableAssert.IsEmpty(provider.Providers);
        }
        public void Constructor2_EmptyArrayAsProvidersArgument_ShouldSetProvidersPropertyToEmpty()
        {
            var provider = new AggregateExportProvider((IEnumerable<ExportProvider>)new ExportProvider[0]);

            EnumerableAssert.IsEmpty(provider.Providers);
        }
        public void Constructor1_NullAsProvidersArgument_ShouldSetProvidersPropertyToEmpty()
        {
            var provider = new AggregateExportProvider((ExportProvider[])null);

            EnumerableAssert.IsEmpty(provider.Providers);
        }
Beispiel #11
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;
                    INotifyComposablePartCatalogChanged catalogToUnsubscribeFrom = null;
                    HashSet <IDisposable>   partsToDispose          = null;
                    ImportEngine            importEngine            = null;
                    ExportProvider          sourceProvider          = null;
                    AggregateExportProvider aggregateExportProvider = null;
                    try
                    {
                        using (this._lock.LockStateForWrite())
                        {
                            if (!this._isDisposed)
                            {
                                catalogToUnsubscribeFrom = this._catalog as INotifyComposablePartCatalogChanged;
                                this._catalog            = null;

                                aggregateExportProvider   = this._innerExportProvider as AggregateExportProvider;
                                this._innerExportProvider = 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 (aggregateExportProvider != null)
                        {
                            aggregateExportProvider.Dispose();
                        }

                        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();
                        }
                    }
                }
            }
        }