예제 #1
0
        /// <summary>
        ///     Constructs a graph starting from the given graph entry points, evaluating with the provided project collection.
        /// </summary>
        /// <param name="entryPoints">The entry points to use in constructing the graph</param>
        /// <param name="projectCollection">
        ///     The collection with which all projects in the graph should be associated. May not be
        ///     null.
        /// </param>
        /// <param name="projectInstanceFactory">
        ///     A delegate used for constructing a <see cref="ProjectInstance" />, called for each
        ///     project created during graph creation. This value can be null, which uses
        ///     a default implementation that calls the ProjectInstance constructor. See the remarks
        ///     on <see cref="ProjectInstanceFactoryFunc" /> for other scenarios.
        /// </param>
        /// <param name="degreeOfParallelism">
        ///     Number of threads to participate in building the project graph.
        /// </param>
        /// <param name="cancellationToken">
        ///     The <see cref="T:System.Threading.CancellationToken" /> token to observe.
        /// </param>
        /// <exception cref="InvalidProjectFileException">
        ///     If the evaluation of any project in the graph fails
        /// </exception>
        /// <exception cref="InvalidOperationException">
        ///     If a null reference is returned from <paramref name="projectInstanceFactory" />
        /// </exception>
        /// <exception cref="CircularDependencyException">
        ///     If the evaluation is successful but the project graph contains a circular
        ///     dependency
        /// </exception>
        public ProjectGraph(
            IEnumerable <ProjectGraphEntryPoint> entryPoints,
            ProjectCollection projectCollection,
            ProjectInstanceFactoryFunc projectInstanceFactory,
            int degreeOfParallelism,
            CancellationToken cancellationToken)
        {
            ErrorUtilities.VerifyThrowArgumentNull(projectCollection, nameof(projectCollection));

            projectInstanceFactory = projectInstanceFactory ?? DefaultProjectInstanceFactory;

            var graphBuilder = new GraphBuilder(
                entryPoints,
                projectCollection,
                projectInstanceFactory,
                ProjectInterpretation.Instance,
                degreeOfParallelism,
                cancellationToken);

            graphBuilder.BuildGraph();

            EntryPointNodes = graphBuilder.EntryPointNodes;
            GraphRoots      = graphBuilder.RootNodes;
            ProjectNodes    = graphBuilder.ProjectNodes;
            Edges           = graphBuilder.Edges;

            _projectNodesTopologicallySorted = new Lazy <IReadOnlyCollection <ProjectGraphNode> >(() => TopologicalSort(GraphRoots, ProjectNodes));
        }
예제 #2
0
        public ProjectGraph(
            IEnumerable <ProjectGraphEntryPoint> entryPoints,
            ProjectCollection projectCollection,
            ProjectInstanceFactoryFunc projectInstanceFactory,
            int degreeOfParallelism,
            CancellationToken cancellationToken)
        {
            ErrorUtilities.VerifyThrowArgumentNull(projectCollection, nameof(projectCollection));

            var measurementInfo = BeginMeasurement();

            projectInstanceFactory ??= DefaultProjectInstanceFactory;

            var graphBuilder = new GraphBuilder(
                entryPoints,
                projectCollection,
                projectInstanceFactory,
                ProjectInterpretation.Instance,
                degreeOfParallelism,
                cancellationToken);

            graphBuilder.BuildGraph();

            EntryPointNodes = graphBuilder.EntryPointNodes;
            GraphRoots      = graphBuilder.RootNodes;
            ProjectNodes    = graphBuilder.ProjectNodes;
            Edges           = graphBuilder.Edges;

            _projectNodesTopologicallySorted = new Lazy <IReadOnlyCollection <ProjectGraphNode> >(() => TopologicalSort(GraphRoots, ProjectNodes));

            ConstructionMetrics = EndMeasurement();

            (Stopwatch Timer, string ETWArgs) BeginMeasurement()
            {
                string etwArgs = null;

                if (MSBuildEventSource.Log.IsEnabled())
                {
                    etwArgs = string.Join(";", entryPoints.Select(
                                              e =>
                    {
                        var globalPropertyString = e.GlobalProperties == null
                                ? string.Empty
                                : string.Join(", ", e.GlobalProperties.Select(kvp => $"{kvp.Key} = {kvp.Value}"));

                        return($"{e.ProjectFile}({globalPropertyString})");
                    }));

                    MSBuildEventSource.Log.ProjectGraphConstructionStart(etwArgs);
                }

                return(Stopwatch.StartNew(), etwArgs);
            }

            GraphConstructionMetrics EndMeasurement()
            {
                if (MSBuildEventSource.Log.IsEnabled())
                {
                    MSBuildEventSource.Log.ProjectGraphConstructionStop(measurementInfo.ETWArgs);
                }

                measurementInfo.Timer.Stop();

                return(new GraphConstructionMetrics(
                           measurementInfo.Timer.Elapsed,
                           ProjectNodes.Count,
                           Edges.Count));
            }
        }