File: System\ComponentModel\Composition\Hosting\CatalogExportProvider.ScopeFactoryExport.cs
Web Access
Project: src\src\libraries\System.ComponentModel.Composition\src\System.ComponentModel.Composition.csproj (System.ComponentModel.Composition)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.ComponentModel.Composition.Primitives;
using System.Diagnostics;
using System.Threading;
 
namespace System.ComponentModel.Composition.Hosting
{
    public partial class CatalogExportProvider
    {
        internal sealed class ScopeFactoryExport : FactoryExport
        {
            private readonly ScopeManager _scopeManager;
            private readonly CompositionScopeDefinition _catalog;
 
            internal ScopeFactoryExport(ScopeManager scopeManager, CompositionScopeDefinition catalog, ComposablePartDefinition partDefinition, ExportDefinition exportDefinition) :
                base(partDefinition, exportDefinition)
            {
                _scopeManager = scopeManager;
                _catalog = catalog;
            }
 
            public override Export CreateExportProduct()
            {
                return new ScopeCatalogExport(this);
            }
 
            private sealed class ScopeCatalogExport : Export, IDisposable
            {
                private readonly ScopeFactoryExport _scopeFactoryExport;
                private CompositionContainer? _childContainer;
                private Export? _export;
                private readonly object _lock = new object();
 
                public ScopeCatalogExport(ScopeFactoryExport scopeFactoryExport)
                {
                    _scopeFactoryExport = scopeFactoryExport;
                }
 
                public override ExportDefinition Definition
                {
                    get
                    {
                        return _scopeFactoryExport.UnderlyingExportDefinition;
                    }
                }
 
                protected override object? GetExportedValueCore()
                {
                    if (_export == null)
                    {
                        CompositionContainer? childContainer = _scopeFactoryExport._scopeManager.CreateChildContainer(_scopeFactoryExport._catalog);
 
                        Debug.Assert(childContainer.CatalogExportProvider != null);
                        Export? export = childContainer.CatalogExportProvider.CreateExport(_scopeFactoryExport.UnderlyingPartDefinition, _scopeFactoryExport.UnderlyingExportDefinition, false, CreationPolicy.Any);
                        lock (_lock)
                        {
                            if (_export == null)
                            {
                                _childContainer = childContainer;
                                Thread.MemoryBarrier();
                                _export = export;
 
                                childContainer = null;
                                export = null;
                            }
                        }
                        childContainer?.Dispose();
                    }
 
                    return _export.Value;
                }
 
                public void Dispose()
                {
                    CompositionContainer? childContainer = null;
                    Export? export;
 
                    if (_export != null)
                    {
                        lock (_lock)
                        {
                            export = _export;
                            childContainer = _childContainer;
 
                            _childContainer = null;
                            Thread.MemoryBarrier();
                            _export = null;
                        }
                    }
 
                    childContainer?.Dispose();
                }
            }
        }
    }
}