예제 #1
0
        public async Task Combined_IncrementalProgressUpdates()
        {
            var discovery  = PartDiscovery.Combine(TestUtilities.V2Discovery, TestUtilities.V1Discovery);
            var assemblies = new[]
            {
                typeof(AssemblyDiscoveryTests.DiscoverablePart1).GetTypeInfo().Assembly,
                this.GetType().GetTypeInfo().Assembly,
            };
            DiscoveryProgress lastReceivedUpdate = default(DiscoveryProgress);
            int progressUpdateCount = 0;
            var progress            = new SynchronousProgress <DiscoveryProgress>(update =>
            {
                progressUpdateCount++;
                Assert.NotNull(update.Status);
                ////Assert.True(update.Completion >= lastReceivedUpdate.Completion); // work can be discovered that regresses this legitimately
                Assert.True(update.Completion <= 1);
                Assert.True(update.Status != lastReceivedUpdate.Status || update.Completion != lastReceivedUpdate.Completion);
                this.output.WriteLine(
                    "Completion reported: {0} ({1}/{2}): {3}",
                    update.Completion,
                    update.CompletedSteps,
                    update.TotalSteps,
                    update.Status);
                lastReceivedUpdate = update;
            });
            await discovery.CreatePartsAsync(assemblies, progress);

            progress.RethrowAnyExceptions();
            Assert.True(lastReceivedUpdate.Completion > 0);
            Assert.True(progressUpdateCount > 2);
        }
예제 #2
0
        private IReadOnlyList <PartDiscovery> GetV3DiscoveryModules()
        {
            var titleAppends = new List <string>();

            var discovery = new List <PartDiscovery>();

            if (this.compositionVersions.HasFlag(CompositionEngines.V3EmulatingV1))
            {
#if DESKTOP
                discovery.Add(TestUtilities.V1Discovery);
                titleAppends.Add("V1");
#endif
            }

            var v2Discovery = this.compositionVersions.HasFlag(CompositionEngines.V3EmulatingV2WithNonPublic)
                ? TestUtilities.V2DiscoveryWithNonPublics
                : TestUtilities.V2Discovery;
            if (this.compositionVersions.HasFlag(CompositionEngines.V3EmulatingV2))
            {
                discovery.Add(v2Discovery);
                titleAppends.Add("V2");
            }

            if (this.compositionVersions.HasFlag(CompositionEngines.V3EmulatingV1AndV2AtOnce))
            {
#if DESKTOP
                discovery.Add(PartDiscovery.Combine(TestUtilities.V1Discovery, v2Discovery));
                titleAppends.Add("V1+V2");
#endif
            }

            this.DisplayName += " (" + string.Join(", ", titleAppends) + ")";

            return(discovery);
        }
예제 #3
0
        public async Task Initialize()
        {
            if (_initialized)
            {
                return;
            }

            var discovery = PartDiscovery.Combine(new AttributedPartDiscoveryV1(Resolver.DefaultInstance));

            var catalog = ComposableCatalog.Create(Resolver.DefaultInstance)
                          .AddParts(await discovery.CreatePartsAsync(Assembly.GetExecutingAssembly()))
                          .AddParts(await discovery.CreatePartsAsync(Assembly.GetCallingAssembly()))
                          .AddParts(await discovery.CreatePartsAsync(Assembly.GetEntryAssembly()))
                          .AddParts(await discovery.CreatePartsAsync(_directoryCatalog.Assemblies))
                          .WithCompositionService(); // Makes an ICompositionService export available to MEF parts to import

            // Assemble the parts into a valid graph.
            var config = CompositionConfiguration.Create(catalog);

            // Prepare an ExportProvider factory based on this graph.
            Factory = config.CreateExportProviderFactory();

            // Create an export provider, which represents a unique container of values.
            ExportProvider = Factory.CreateExportProvider();

            CompositionService = ExportProvider.GetExportedValue <ICompositionService>();

            _initialized = true;
        }
예제 #4
0
        public async Task Combined_CreatePartsAsync_TypeArray_ResilientAgainstReflectionErrors()
        {
            var discovery = PartDiscovery.Combine(new SketchyPartDiscovery(), new NoOpDiscovery());
            var parts     = await discovery.CreatePartsAsync(typeof(string), typeof(int));

            Assert.Equal(1, parts.DiscoveryErrors.Count);
            Assert.Equal(1, parts.Parts.Count);
        }
예제 #5
0
        public void Combine_JustOneButWithDifferentResolver()
        {
            LoggingAssemblyLoader assemblyLoader = new();
            Resolver      assemblyResolver       = new(assemblyLoader);
            PartDiscovery combined = PartDiscovery.Combine(assemblyResolver, TestUtilities.V1Discovery);

            Assert.NotSame(TestUtilities.V1Discovery, combined);
            Assert.Same(assemblyResolver, combined.Resolver);
        }
예제 #6
0
        public override bool Execute()
        {
            var resolver  = Resolver.DefaultInstance;
            var discovery = PartDiscovery.Combine(new AttributedPartDiscoveryV1(resolver), new AttributedPartDiscovery(resolver, isNonPublicSupported: true));

            this.CancellationToken.ThrowIfCancellationRequested();

            var parts = discovery.CreatePartsAsync(this.CatalogAssemblies.Select(item => item.ItemSpec)).GetAwaiter().GetResult();

            foreach (var error in parts.DiscoveryErrors)
            {
                this.Log.LogWarningFromException(error);
            }

            this.CancellationToken.ThrowIfCancellationRequested();
            var catalog = ComposableCatalog.Create(resolver)
                          .AddParts(parts.Parts);

            this.CancellationToken.ThrowIfCancellationRequested();
            var configuration = CompositionConfiguration.Create(catalog);

            if (!string.IsNullOrEmpty(this.DgmlOutputPath))
            {
                configuration.CreateDgml().Save(this.DgmlOutputPath);
            }

            this.CancellationToken.ThrowIfCancellationRequested();
            if (!configuration.CompositionErrors.IsEmpty)
            {
                foreach (var error in configuration.CompositionErrors.Peek())
                {
                    this.Log.LogError(error.Message);
                }

                return(false);
            }

            this.CancellationToken.ThrowIfCancellationRequested();

            string cachePath = Path.GetFullPath(this.CompositionCacheFile);

            this.Log.LogMessage("Producing IoC container \"{0}\"", cachePath);
            using (var cacheStream = File.Open(cachePath, FileMode.Create))
            {
                this.CancellationToken.ThrowIfCancellationRequested();
                var runtime = RuntimeComposition.CreateRuntimeComposition(configuration);
                this.CancellationToken.ThrowIfCancellationRequested();
                var runtimeCache = new CachedComposition();
                runtimeCache.SaveAsync(runtime, cacheStream, this.CancellationToken).GetAwaiter().GetResult();
            }

            return(!this.Log.HasLoggedErrors);
        }
예제 #7
0
        public async Task Combined_CreatePartsAsync_AssemblyPathEnumerable()
        {
            var discovery  = PartDiscovery.Combine(TestUtilities.V2Discovery, TestUtilities.V1Discovery);
            var assemblies = new[]
            {
                typeof(AssemblyDiscoveryTests.DiscoverablePart1).GetTypeInfo().Assembly,
                this.GetType().GetTypeInfo().Assembly,
            };
            var parts = await discovery.CreatePartsAsync(assemblies.Select(a => a.Location));

            Assert.NotEqual(0, parts.Parts.Count);
        }
예제 #8
0
        public async Task DiscoveriesCombinedWithResolver()
        {
            LoggingAssemblyLoader assemblyLoader = new();
            Resolver      assemblyResolver       = new(assemblyLoader);
            PartDiscovery combined = PartDiscovery.Combine(assemblyResolver, TestUtilities.V2Discovery, TestUtilities.V1Discovery);

            Assert.Same(assemblyResolver, combined.Resolver);
            string testAssemblyPath = typeof(PartDiscoveryTests).Assembly.Location;
            await combined.CreatePartsAsync(new string[] { testAssemblyPath });

            Assert.Equal(new[] { testAssemblyPath }, assemblyLoader.AttemptedAssemblyPaths);
        }
예제 #9
0
        public async Task AssemblyDiscoveryOmitsNonDiscoverableParts_Combined()
        {
            var combined = PartDiscovery.Combine(this.DiscoveryService, new PartDiscoveryAllTypesMock());
            var result   = await combined.CreatePartsAsync(typeof(NonDiscoverablePart).GetTypeInfo().Assembly);

            Assert.False(result.Parts.Any(p => p.Type.GetTypeInfo().IsEquivalentTo(typeof(NonPart))));
            Assert.False(result.Parts.Any(p => p.Type.GetTypeInfo().IsEquivalentTo(typeof(NonDiscoverablePart))));
            Assert.False(result.Parts.Any(p => p.Type.GetTypeInfo().IsEquivalentTo(typeof(NonDiscoverablePartV1))));
            Assert.False(result.Parts.Any(p => p.Type.GetTypeInfo().IsEquivalentTo(typeof(NonDiscoverablePartV2))));

            Assert.True(result.Parts.Any(p => p.Type.GetTypeInfo().IsEquivalentTo(typeof(DiscoverablePart1))));
            Assert.True(result.Parts.Any(p => p.Type.GetTypeInfo().IsEquivalentTo(typeof(DiscoverablePart2))));
        }
예제 #10
0
        private static ExportProvider CreateExportProvider(string applicationDataFolder)
        {
            var stopwatch = Stopwatch.StartNew();

            var file = new FileInfo(Application.ExecutablePath);

            FileInfo[] plugins =
                Directory.Exists(Path.Combine(file.Directory.FullName, "Plugins"))
                ? new DirectoryInfo(Path.Combine(file.Directory.FullName, "Plugins")).GetFiles("*.dll")
                : new FileInfo[] { };

            var pluginFiles = plugins;

            var cacheFile = Path.Combine(applicationDataFolder ?? "ignored", "Plugins", "composition.cache");
            IExportProviderFactory exportProviderFactory;

            if (applicationDataFolder != null && File.Exists(cacheFile))
            {
                using (var cacheStream = File.OpenRead(cacheFile))
                {
                    exportProviderFactory = ThreadHelper.JoinableTaskFactory.Run(() => new CachedComposition().LoadExportProviderFactoryAsync(cacheStream, Resolver.DefaultInstance));
                }
            }
            else
            {
                var assemblies = pluginFiles.Select(assemblyFile => TryLoadAssembly(assemblyFile)).Where(assembly => assembly != null).ToArray();

                var discovery = PartDiscovery.Combine(
                    new AttributedPartDiscoveryV1(Resolver.DefaultInstance),
                    new AttributedPartDiscovery(Resolver.DefaultInstance, isNonPublicSupported: true));
                var parts   = ThreadHelper.JoinableTaskFactory.Run(() => discovery.CreatePartsAsync(assemblies));
                var catalog = ComposableCatalog.Create(Resolver.DefaultInstance).AddParts(parts);

                var configuration      = CompositionConfiguration.Create(catalog.WithCompositionService());
                var runtimeComposition = RuntimeComposition.CreateRuntimeComposition(configuration);
                if (applicationDataFolder != null)
                {
#if false // Composition caching currently disabled
                    Directory.CreateDirectory(Path.Combine(applicationDataFolder, "Plugins"));
                    using (var cacheStream = File.OpenWrite(cacheFile))
                    {
                        ThreadHelper.JoinableTaskFactory.Run(() => new CachedComposition().SaveAsync(runtimeComposition, cacheStream));
                    }
#endif
                }

                exportProviderFactory = runtimeComposition.CreateExportProviderFactory();
            }

            return(exportProviderFactory.CreateExportProvider());
        }
예제 #11
0
            internal void CreateCache(string assemblyPath, Stream cacheStream, out int metadataToken)
            {
                Requires.NotNullOrEmpty(assemblyPath, nameof(assemblyPath));

                var resolver = new Resolver(new CustomAssemblyLoader(assemblyPath));
                var discovery = PartDiscovery.Combine(
                    new AttributedPartDiscovery(resolver, isNonPublicSupported: true),
                    new AttributedPartDiscoveryV1(resolver));
                var discoveredParts = discovery.CreatePartsAsync(new[] { assemblyPath }).GetAwaiter().GetResult();
                var catalog = ComposableCatalog.Create(resolver)
                    .AddParts(discoveredParts);
                var configuration = CompositionConfiguration.Create(catalog);
                this.cacheManager.SaveAsync(configuration, cacheStream).GetAwaiter().GetResult();
                metadataToken = GetMetadataTokenForDefaultCtor(catalog.Parts.Single(p => p.TypeRef.FullName == typeof(DiscoverablePart1).FullName).Type);
            }
예제 #12
0
        public static async Task <ComposableCatalog> CreateCatalog(HashSet <Assembly> assemblies = null)
        {
            Resolver      StandardResolver = Resolver.DefaultInstance;
            PartDiscovery Discovery        = PartDiscovery.Combine(
                new AttributedPartDiscoveryV1(StandardResolver),
                new AttributedPartDiscovery(StandardResolver, true));

            var parts = await Discovery.CreatePartsAsync(assemblies ?? ReadAssembliesFromAddins());

            ComposableCatalog catalog = ComposableCatalog.Create(StandardResolver)
                                        .WithCompositionService()
                                        .WithDesktopSupport()
                                        .AddParts(parts);

            return(catalog);
        }
예제 #13
0
        private static PartDiscovery GetDiscoveryService(CompositionEngines attributesDiscovery)
        {
            var discovery = new List <PartDiscovery>(2);

            if (attributesDiscovery.HasFlag(CompositionEngines.V1))
            {
                discovery.Add(V1Discovery);
            }

            if (attributesDiscovery.HasFlag(CompositionEngines.V2))
            {
                var v2Discovery = attributesDiscovery.HasFlag(CompositionEngines.V3NonPublicSupport)
                    ? V2DiscoveryWithNonPublics
                    : V2Discovery;
                discovery.Add(v2Discovery);
            }

            return(PartDiscovery.Combine(discovery.ToArray()));
        }
예제 #14
0
        private async Task <ExportProvider> Compose(object parentInstance)
        {
            ExportProvider exportProvider = null;
            PartDiscovery  discovery      = PartDiscovery.Combine(
                new AttributedPartDiscovery(Resolver.DefaultInstance),
                new AttributedPartDiscoveryV1(Resolver.DefaultInstance)); // ".NET MEF" attributes (System.ComponentModel.Composition)

            Assembly parentAssembly = parentInstance.GetType().Assembly;
            string   parentLocation = parentAssembly.Location;
            string   assemblyPath   = parentLocation;

            assemblyPath = assemblyPath.Substring(0, assemblyPath.LastIndexOf('\\'));

            Helpers       desktopBridgeHelper = new Helpers();
            List <string> assemblies          = new[] { parentLocation }
            .Concat(
                Directory.EnumerateFiles(assemblyPath, "*.dll", SearchOption.TopDirectoryOnly)
                .Where(_ => _.Contains("NUnit3GUI")))
            .ToList();

            DiscoveredParts discoveredParts = await discovery.CreatePartsAsync(assemblies);

            discoveredParts.ThrowOnErrors();

            ComposableCatalog catalog = ComposableCatalog.Create(Resolver.DefaultInstance)
                                        .AddParts(discoveredParts)
                                        .WithCompositionService();

            CompositionConfiguration config = CompositionConfiguration.Create(catalog);

            config.ThrowOnErrors();

            IExportProviderFactory epf = config.CreateExportProviderFactory();

            exportProvider = epf.CreateExportProvider();

            ICompositionService service = exportProvider.GetExportedValue <ICompositionService>();

            service.SatisfyImportsOnce(parentInstance);

            return(exportProvider);
        }
        public ComponentComposition()
        {
            var discovery = PartDiscovery.Combine(new AttributedPartDiscoveryV1(Resolver.DefaultInstance),
                                                  new AttributedPartDiscovery(Resolver.DefaultInstance, isNonPublicSupported: true));

            var parts      = discovery.CreatePartsAsync(BuildInAssemblies).GetAwaiter().GetResult();
            var scopeParts = discovery.CreatePartsAsync(typeof(UnconfiguredProjectScope), typeof(ConfiguredProjectScope), typeof(ProjectServiceScope), typeof(GlobalScope)).GetAwaiter().GetResult();

            ComposableCatalog catalog = ComposableCatalog.Create(Resolver.DefaultInstance)
                                        .AddParts(parts)
                                        .AddParts(scopeParts)
                                        .WithCompositionService();

            // Prepare the self-host service and composition
            Catalog       = catalog;
            Configuration = CompositionConfiguration.Create(catalog);
            Contracts     = CollectContractMetadata(ContractAssemblies.Union(BuildInAssemblies));
            ContractsRequiringAppliesTo = CollectContractsRequiringAppliesTo(catalog);
            InterfaceNames = CollectInterfaceNames(ContractAssemblies);
        }
 public static PartDiscovery CreatePartDiscovery(Resolver resolver)
 {
     return(PartDiscovery.Combine(new AttributedPartDiscoveryV1(resolver), new AttributedPartDiscovery(resolver, isNonPublicSupported: true)));
 }
예제 #17
0
        public void Combine_JustOneButWithSameResolver()
        {
            PartDiscovery combined = PartDiscovery.Combine(TestUtilities.V1Discovery.Resolver, TestUtilities.V1Discovery);

            Assert.Same(TestUtilities.V1Discovery, combined);
        }
예제 #18
0
        /// <summary>
        /// Creates a reusable environment that consists of
        /// 1) default parts and parts needed to bootstrap the editor, except for parts whose metadata matches these from <paramref name="typesThatOverride"></paramref>
        /// 2) parts found in the provided assemblies
        /// 3) parts found in the provided types.
        /// </summary>
        /// <param name="assembliesToLoad">Filenames of assemblies that will be searched for MEF parts.</param>
        /// <param name="typesToLoad">Types to include in the MEF catalog.</param>
        /// <param name="typesThatOverride">Types whose export signatures will be used to filter out the default catalog.</param>
        /// <returns>Composed environment that can be reused across tests</returns>
        public static async Task <EditorEnvironment> InitializeAsync(IEnumerable <string> assembliesToLoad, IEnumerable <Type> typesToLoad, IEnumerable <Type> typesThatOverride)
        {
            // Prepare part discovery to support both flavors of MEF attributes.
            var discovery = PartDiscovery.Combine(
                new AttributedPartDiscovery(Resolver.DefaultInstance, isNonPublicSupported: true), // "NuGet MEF" attributes (Microsoft.Composition)
                new AttributedPartDiscoveryV1(Resolver.DefaultInstance));                          // ".NET MEF" attributes (System.ComponentModel.Composition)

            var assemblyCatalog = ComposableCatalog.Create(Resolver.DefaultInstance);

            // Create a list of parts that should override the defaults. Used for mocking when Import expects only one part.
            IEnumerable <ComposablePartDefinition> partsThatOverride = null;

            if (typesThatOverride != null)
            {
                partsThatOverride = (await discovery.CreatePartsAsync(typesThatOverride)).Parts;
            }

            // Load default parts
            foreach (var assemblyName in DefaultAssemblies)
            {
                try
                {
                    var parts = (await discovery.CreatePartsAsync(Assembly.LoadFrom(assemblyName))).Parts;
                    if (partsThatOverride != null)
                    {
                        // Exclude parts whose contract matches the contract of any of the overriding parts
                        var overriddenParts = parts.Where(defaultPart => defaultPart.ExportedTypes.Any(defaultType =>
                                                                                                       partsThatOverride.Any(overridingPart => overridingPart.ExportedTypes.Any(overridingType => overridingType.ContractName == defaultType.ContractName))));
                        parts = parts.Except(overriddenParts);
                    }
                    assemblyCatalog = assemblyCatalog.AddParts(parts);
                }
                catch (System.IO.FileNotFoundException)
                {
                    // Note, if we provide inner exception, the MSTest runner will display it instead of informativeException. For this reason, we don't provide inner exception.
                    var informativeException = new InvalidOperationException($"Required assembly `{assemblyName}` not found. Please place it in this process' working directory. You can do it by adding reference to the NuGet package that contains this assembly.");
                    informativeException.Data["Missing file"] = assemblyName;
                    throw informativeException;
                }
            }

            // Load parts from all types in the specified assemblies
            if (assembliesToLoad != null)
            {
                foreach (string assembly in assembliesToLoad)
                {
                    var parts = await discovery.CreatePartsAsync(Assembly.LoadFrom(assembly));

                    assemblyCatalog = assemblyCatalog.AddParts(parts);
                }
            }

            // Load parts from the specified types
            if (typesToLoad != null)
            {
                var parts = await discovery.CreatePartsAsync(typesToLoad);

                assemblyCatalog = assemblyCatalog.AddParts(parts);
            }

            // TODO: see if this will be useful
            assemblyCatalog = assemblyCatalog.WithCompositionService(); // Makes an ICompositionService export available to MEF parts to import.

            // Assemble the parts into a valid graph.
            var compositionConfiguration = CompositionConfiguration.Create(assemblyCatalog);

            ImmutableArray <string> compositionErrors = ImmutableArray <string> .Empty;

            if (compositionConfiguration.CompositionErrors.Any())
            {
                compositionErrors = compositionConfiguration.CompositionErrors.SelectMany(collection => collection.Select(diagnostic => diagnostic.Message)).ToImmutableArray();
                // Uncomment to investigate errors and continue execution
                // Debugger.Break();

                // Uncomment to fail immediately:
                // var exception = new InvalidOperationException("There were composition errors");
                // exception.Data["Errors"] = errors;
                // throw exception;
            }

            // Prepare an ExportProvider factory based on this graph.
            // This factory can be now re-used across tests
            return(new EditorEnvironment(compositionConfiguration.CreateExportProviderFactory(), compositionErrors));
        }
예제 #19
0
        public override bool Execute()
        {
            if (Environment.GetEnvironmentVariable("CreateCompositionTaskDebug") == "1")
            {
                Debugger.Launch();
            }

            this.catalogAssemblyPaths.AddRange(this.CatalogAssemblies.Select(this.GetMEFAssemblyFullPath));

            AppDomain.CurrentDomain.AssemblyResolve += this.CurrentDomain_AssemblyResolve;
            try
            {
                var loadableAssemblies = this.catalogAssemblyPaths
                                         .Concat(this.ReferenceAssemblies.Select(i => i.GetMetadata("FullPath")) ?? Enumerable.Empty <string>());
                var resolver  = new Resolver(new AssemblyLoader(loadableAssemblies));
                var discovery = PartDiscovery.Combine(
                    new AttributedPartDiscoveryV1(resolver),
                    new AttributedPartDiscovery(resolver, isNonPublicSupported: true));

                this.CancellationToken.ThrowIfCancellationRequested();

                var parts   = discovery.CreatePartsAsync(this.catalogAssemblyPaths).GetAwaiter().GetResult();
                var catalog = ComposableCatalog.Create(resolver)
                              .AddParts(parts);

                this.LogLines(this.GetLogFilePath("CatalogAssemblies"), this.GetCatalogAssembliesLines(catalog), this.CancellationToken);

                string catalogErrorFilePath = this.GetLogFilePath("CatalogErrors");
                if (catalog.DiscoveredParts.DiscoveryErrors.IsEmpty)
                {
                    File.Delete(catalogErrorFilePath);
                }
                else
                {
                    this.LogLines(catalogErrorFilePath, GetCatalogErrorLines(catalog), this.CancellationToken);
                    foreach (var error in catalog.DiscoveredParts.DiscoveryErrors)
                    {
                        string message = error.GetUserMessage();
                        if (this.ContinueOnDiscoveryErrors)
                        {
                            this.LogWarning(DiscoveryErrorCode, message);
                        }
                        else
                        {
                            this.Log.LogError(null, DiscoveryErrorCode, null, null, 0, 0, 0, 0, message);
                        }
                    }

                    if (!this.ContinueOnDiscoveryErrors)
                    {
                        return(false);
                    }
                }

                this.CancellationToken.ThrowIfCancellationRequested();
                var configuration = CompositionConfiguration.Create(catalog);

                if (!string.IsNullOrEmpty(this.DgmlOutputPath))
                {
                    configuration.CreateDgml().Save(this.DgmlOutputPath);
                    this.writtenFiles.Add(this.DgmlOutputPath);
                }

                this.CancellationToken.ThrowIfCancellationRequested();
                string compositionLogPath = this.GetLogFilePath("CompositionErrors");
                if (configuration.CompositionErrors.IsEmpty)
                {
                    File.Delete(compositionLogPath);
                }
                else
                {
                    this.LogLines(compositionLogPath, GetCompositionErrorLines(configuration), this.CancellationToken);
                    foreach (var error in configuration.CompositionErrors.Peek())
                    {
                        if (this.ContinueOnCompositionErrors)
                        {
                            this.LogWarning(CompositionErrorCode, error.Message);
                        }
                        else
                        {
                            this.Log.LogError(null, CompositionErrorCode, null, null, 0, 0, 0, 0, error.Message);
                        }
                    }

                    if (!this.ContinueOnCompositionErrors)
                    {
                        return(false);
                    }
                }

                this.CancellationToken.ThrowIfCancellationRequested();

                string cachePath = Path.GetFullPath(this.CompositionCacheFile);
                this.Log.LogMessage("Producing IoC container \"{0}\"", cachePath);
                using (var cacheStream = File.Open(cachePath, FileMode.Create))
                {
                    this.CancellationToken.ThrowIfCancellationRequested();
                    var runtime = RuntimeComposition.CreateRuntimeComposition(configuration);
                    this.CancellationToken.ThrowIfCancellationRequested();
                    var runtimeCache = new CachedComposition();
                    runtimeCache.SaveAsync(runtime, cacheStream, this.CancellationToken).GetAwaiter().GetResult();
                }

                this.writtenFiles.Add(cachePath);

                return(!this.Log.HasLoggedErrors);
            }
            finally
            {
                AppDomain.CurrentDomain.AssemblyResolve -= this.CurrentDomain_AssemblyResolve;
                this.FileWrites = this.writtenFiles.Select(f => new TaskItem(f)).ToArray();
            }
        }