Exemplo n.º 1
0
 public CompositionConfiguration GetCompositionConfiguration()
 => CompositionConfiguration.Create(GetCatalog());
Exemplo n.º 2
0
        protected override async Task <RunSummary> RunTestAsync()
        {
            var output = new TestOutputHelper();

            output.Initialize(this.MessageBus, new XunitTest(this.TestCase, this.DisplayName));
            await this.Aggregator.RunAsync(() => this.Timer.AggregateAsync(
                                               async delegate
            {
                var v3DiscoveryModules = this.GetV3DiscoveryModules();

                var resultingCatalogs = new List <ComposableCatalog>(v3DiscoveryModules.Count);

                var assemblies = this.assemblyNames.Select(an => Assembly.Load(new AssemblyName(an))).ToList();
                foreach (var discoveryModule in v3DiscoveryModules)
                {
                    var partsFromTypes      = await discoveryModule.CreatePartsAsync(this.parts);
                    var partsFromAssemblies = await discoveryModule.CreatePartsAsync(assemblies);
                    var catalog             = TestUtilities.EmptyCatalog
                                              .AddParts(partsFromTypes)
                                              .AddParts(partsFromAssemblies);
                    resultingCatalogs.Add(catalog);
                }

                string[] catalogStringRepresentations = resultingCatalogs.Select(catalog =>
                {
                    var writer = new StringWriter();
                    catalog.ToString(writer);
                    return(writer.ToString());
                }).ToArray();

                bool anyStringRepresentationDifferences = false;
                for (int i = 1; i < resultingCatalogs.Count; i++)
                {
                    anyStringRepresentationDifferences = PrintDiff(
                        v3DiscoveryModules[0].GetType().Name,
                        v3DiscoveryModules[i].GetType().Name,
                        catalogStringRepresentations[0],
                        catalogStringRepresentations[i],
                        output);
                }

                // Verify that the catalogs are identical.
                // The string compare above should have taken care of this (in a more descriptive way),
                // but we do this to double-check.
                var uniqueCatalogs = resultingCatalogs.Distinct().ToArray();

                // Fail the test if ComposableCatalog.Equals returns a different result from string comparison.
                Assert.Equal(anyStringRepresentationDifferences, uniqueCatalogs.Length > 1);

                if (uniqueCatalogs.Length == 1)
                {
                    ////output.WriteLine(catalogStringRepresentations[0]);
                }

                // For each distinct catalog, create one configuration and verify it meets expectations.
                var configurations = new List <CompositionConfiguration>(uniqueCatalogs.Length);
                foreach (var uniqueCatalog in uniqueCatalogs)
                {
                    var catalogWithSupport = uniqueCatalog
#if DESKTOP
                                             .WithCompositionService()
#endif
                    ;

                    // Round-trip the catalog through serialization to verify that as well.
                    await RoundtripCatalogSerializationAsync(catalogWithSupport, output);

                    var configuration = CompositionConfiguration.Create(catalogWithSupport);

                    if (!this.compositionVersions.HasFlag(CompositionEngines.V3AllowConfigurationWithErrors))
                    {
                        Assert.Equal(this.expectInvalidConfiguration, !configuration.CompositionErrors.IsEmpty || !catalogWithSupport.DiscoveredParts.DiscoveryErrors.IsEmpty);
                    }

                    // Save the configuration in a property so that the engine test that follows can reuse the work we've done.
                    configurations.Add(configuration);
                }

                this.ResultingConfigurations = configurations;
            }));

            var test       = new XunitTest(this.TestCase, this.DisplayName);
            var runSummary = new RunSummary {
                Total = 1, Time = this.Timer.Total
            };
            IMessageSinkMessage testResultMessage;
            if (this.Aggregator.HasExceptions)
            {
                testResultMessage = new TestFailed(test, this.Timer.Total, output.Output, this.Aggregator.ToException());
                runSummary.Failed++;
            }
            else
            {
                testResultMessage = new TestPassed(test, this.Timer.Total, output.Output);
                this.Passed       = true;
            }

            if (!this.MessageBus.QueueMessage(testResultMessage))
            {
                this.CancellationTokenSource.Cancel();
            }

            this.Aggregator.Clear();
            return(runSummary);
        }
Exemplo n.º 3
0
        public Mef3TestCaseRunner(IXunitTestCase testCase, string displayName, string skipReason, object[] constructorArguments, IMessageBus messageBus, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource, CompositionConfiguration configuration, CompositionEngines compositionVersions)
            : base(testCase, displayName, skipReason, constructorArguments, null, messageBus, aggregator, cancellationTokenSource)
        {
            Requires.NotNull(configuration, nameof(configuration));

            this.configuration       = configuration;
            this.compositionVersions = compositionVersions;
        }
 public SingleExportProviderFactory(Scope scope, ComposableCatalog catalog, CompositionConfiguration configuration, IExportProviderFactory exportProviderFactory)
 {
     _scope                 = scope;
     _catalog               = catalog;
     _configuration         = configuration;
     _exportProviderFactory = exportProviderFactory;
 }
Exemplo n.º 5
0
        private static async Task InitializeMef()
        {
            // Cannot show MessageBox here, because WPF would crash with a XamlParseException
            // Remember and show exceptions in text output, once MainWindow is properly initialized
            try
            {
                // Set up VS MEF. For now, only do MEF1 part discovery, since that was in use before.
                // To support both MEF1 and MEF2 parts, just change this to:
                // var discovery = PartDiscovery.Combine(new AttributedPartDiscoveryV1(Resolver.DefaultInstance),
                //                                       new AttributedPartDiscovery(Resolver.DefaultInstance));
                var discovery = new AttributedPartDiscoveryV1(Resolver.DefaultInstance);
                var catalog   = ComposableCatalog.Create(Resolver.DefaultInstance);
                var pluginDir = Path.GetDirectoryName(typeof(App).Module.FullyQualifiedName);
#if NET472
                if (pluginDir != null)
                {
                    foreach (var plugin in Directory.GetFiles(pluginDir, "*.Plugin.dll"))
                    {
                        var name = Path.GetFileNameWithoutExtension(plugin);
                        try
                        {
                            var asm   = Assembly.Load(name);
                            var parts = await discovery.CreatePartsAsync(asm);

                            catalog = catalog.AddParts(parts);
                        }
                        catch (Exception ex)
                        {
                            StartupExceptions.Add(new ExceptionData {
                                Exception = ex, PluginName = name
                            });
                        }
                    }
                }
#endif
                // Add the built-in parts
                var createdParts = await discovery.CreatePartsAsync(Assembly.GetExecutingAssembly());

                catalog = catalog.AddParts(createdParts);
                // If/When the project switches to .NET Standard/Core, this will be needed to allow metadata interfaces (as opposed
                // to metadata classes). When running on .NET Framework, it's automatic.
                //   catalog.WithDesktopSupport();
                // If/When any part needs to import ICompositionService, this will be needed:
                //   catalog.WithCompositionService();
                var config = CompositionConfiguration.Create(catalog);
                ExportProviderFactory = config.CreateExportProviderFactory();
                ExportProvider        = ExportProviderFactory.CreateExportProvider();
                // This throws exceptions for composition failures. Alternatively, the configuration's CompositionErrors property
                // could be used to log the errors directly. Used at the end so that it does not prevent the export provider setup.
                config.ThrowOnErrors();
            }
            catch (CompositionFailedException ex) when(ex.InnerException is AggregateException agex)
            {
                foreach (var inner in agex.InnerExceptions)
                {
                    StartupExceptions.Add(new ExceptionData {
                        Exception = inner
                    });
                }
            }
            catch (Exception ex)
            {
                StartupExceptions.Add(new ExceptionData {
                    Exception = ex
                });
            }
        }
Exemplo n.º 6
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(this, 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();
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Method to initialize the part nodes and thier "pointers" based on the error
        /// stack from the config.
        /// </summary>
        private void GenerateNodeGraph()
        {
            // Get the error stack from the composition configuration
            var expectedRejectionsChecker   = new ExpectedRejections(this.Options);
            CompositionConfiguration config = this.Creator.Config !;
            var errors      = config.CompositionErrors;
            int levelNumber = 1;

            while (errors.Count() > 0)
            {
                // Process all the parts present in the current level of the stack
                var currentLevel = errors.Peek();
                foreach (var element in currentLevel)
                {
                    var part = element.Parts.First();

                    // Create a PartNode object from the definition of the current Part
                    ComposablePartDefinition definition = part.Definition;
                    string currentName = definition.Type.FullName !;
                    if (currentName == null)
                    {
                        continue;
                    }

                    if (this.RejectionGraph.ContainsKey(currentName))
                    {
                        this.RejectionGraph[currentName].AddErrorMessage(element.Message);
                        continue;
                    }

                    PartNode currentNode = new PartNode(definition, element.Message, levelNumber);
                    currentNode.IsRejectionExpected = expectedRejectionsChecker.IsRejectionExpected(currentName);
                    this.RejectionGraph.Add(currentName, currentNode);
                }

                // Get the next level of the stack
                errors       = errors.Pop();
                levelNumber += 1;
            }

            this.MaxLevels = levelNumber - 1;
            foreach (var nodePair in this.RejectionGraph)
            {
                var node            = nodePair.Value;
                var currentNodeName = node.Name;
                var nodeDefinition  = node.Part;

                // Get the imports for the current part to update the pointers associated with the current node
                foreach (var import in nodeDefinition.Imports)
                {
                    string importName = import.ImportingSiteType.FullName !;
                    if (importName == null || !this.RejectionGraph.ContainsKey(importName))
                    {
                        continue;
                    }

                    string importLabel = importName;
                    if (import.ImportingMember != null)
                    {
                        importLabel = import.ImportingMember.Name;
                    }

                    PartNode childNode = this.RejectionGraph[importName];
                    childNode.AddParent(node, importLabel);
                    node.AddChild(childNode, importLabel);
                }
            }
        }
Exemplo n.º 8
0
        public App()
        {
            var cmdArgs = Environment.GetCommandLineArgs().Skip(1);

            App.CommandLineArguments = new CommandLineArguments(cmdArgs);
            if ((App.CommandLineArguments.SingleInstance ?? true) && !MiscSettingsPanel.CurrentMiscSettings.AllowMultipleInstances)
            {
                cmdArgs = cmdArgs.Select(FullyQualifyPath);
                string message = string.Join(Environment.NewLine, cmdArgs);
                if (SendToPreviousInstance("ILSpy:\r\n" + message, !App.CommandLineArguments.NoActivate))
                {
                    Environment.Exit(0);
                }
            }
            InitializeComponent();

            // Cannot show MessageBox here, because WPF would crash with a XamlParseException
            // Remember and show exceptions in text output, once MainWindow is properly initialized
            try {
                // Set up VS MEF. For now, only do MEF1 part discovery, since that was in use before.
                // To support both MEF1 and MEF2 parts, just change this to:
                // var discovery = PartDiscovery.Combine(new AttributedPartDiscoveryV1(Resolver.DefaultInstance),
                //                                       new AttributedPartDiscovery(Resolver.DefaultInstance));
                var discovery = new AttributedPartDiscoveryV1(Resolver.DefaultInstance);
                var catalog   = ComposableCatalog.Create(Resolver.DefaultInstance);
                var pluginDir = Path.GetDirectoryName(typeof(App).Module.FullyQualifiedName);
                if (pluginDir != null)
                {
                    foreach (var plugin in Directory.GetFiles(pluginDir, "*.Plugin.dll"))
                    {
                        var name = Path.GetFileNameWithoutExtension(plugin);
                        try {
                            var asm   = Assembly.Load(name);
                            var parts = discovery.CreatePartsAsync(asm).Result;
                            catalog = catalog.AddParts(parts);
                        } catch (Exception ex) {
                            StartupExceptions.Add(new ExceptionData {
                                Exception = ex, PluginName = name
                            });
                        }
                    }
                }
                // Add the built-in parts
                catalog = catalog.AddParts(discovery.CreatePartsAsync(Assembly.GetExecutingAssembly()).Result);
                // If/When the project switches to .NET Standard/Core, this will be needed to allow metadata interfaces (as opposed
                // to metadata classes). When running on .NET Framework, it's automatic.
                //   catalog.WithDesktopSupport();
                // If/When any part needs to import ICompositionService, this will be needed:
                //   catalog.WithCompositionService();
                var config = CompositionConfiguration.Create(catalog);
                exportProviderFactory = config.CreateExportProviderFactory();
                exportProvider        = exportProviderFactory.CreateExportProvider();
                // This throws exceptions for composition failures. Alternatively, the configuration's CompositionErrors property
                // could be used to log the errors directly. Used at the end so that it does not prevent the export provider setup.
                config.ThrowOnErrors();
            } catch (Exception ex) {
                StartupExceptions.Add(new ExceptionData {
                    Exception = ex
                });
            }

            if (!System.Diagnostics.Debugger.IsAttached)
            {
                AppDomain.CurrentDomain.UnhandledException      += ShowErrorBox;
                Dispatcher.CurrentDispatcher.UnhandledException += Dispatcher_UnhandledException;
            }
            TaskScheduler.UnobservedTaskException += DotNet40_UnobservedTaskException;
            Languages.Initialize(exportProvider);

            EventManager.RegisterClassHandler(typeof(Window),
                                              Hyperlink.RequestNavigateEvent,
                                              new RequestNavigateEventHandler(Window_RequestNavigate));
            ILSpyTraceListener.Install();
        }