private State Initialize(string appPath, string configuration, bool triggerBuildOutputs) { var state = new State { Frameworks = new List <FrameworkData>(), Projects = new List <ProjectInfo>() }; Project project; if (!Project.TryGetProject(appPath, out project)) { throw new InvalidOperationException(string.Format("Unable to find project.json in '{0}'", appPath)); } if (triggerBuildOutputs) { // Trigger the build outputs for this project _namedDependencyProvider.Trigger(project.Name + "_BuildOutputs"); } state.Name = project.Name; state.Configurations = project.GetConfigurations().ToList(); state.Commands = project.Commands; var frameworks = new List <FrameworkName>( project.GetTargetFrameworks() .Select(tf => tf.FrameworkName)); if (!frameworks.Any()) { frameworks.Add(VersionUtility.ParseFrameworkName("aspnet50")); } var appHostContextCache = new Dictionary <Tuple <string, FrameworkName>, ApplicationHostContext>(); // We need to create an app env for the design time host's target framework var runtimeApplicationHostContext = new ApplicationHostContext(_hostServices, appPath, packagesDirectory: null, configuration: _appEnv.Configuration, targetFramework: _appEnv.RuntimeFramework, cache: _cache, cacheContextAccessor: _cacheContextAccessor, namedCacheDependencyProvider: _namedDependencyProvider); runtimeApplicationHostContext.DependencyWalker.Walk(project.Name, project.Version, _appEnv.RuntimeFramework); var runtimeAppHostContextCacheKey = Tuple.Create(_appEnv.Configuration, _appEnv.RuntimeFramework); // TODO: Move this caching to the ICache appHostContextCache[runtimeAppHostContextCacheKey] = runtimeApplicationHostContext; foreach (var frameworkName in frameworks) { var cacheKey = Tuple.Create(configuration, frameworkName); ApplicationHostContext applicationHostContext; if (!appHostContextCache.TryGetValue(cacheKey, out applicationHostContext)) { applicationHostContext = new ApplicationHostContext(_hostServices, appPath, packagesDirectory: null, configuration: configuration, targetFramework: frameworkName, cache: _cache, cacheContextAccessor: _cacheContextAccessor, namedCacheDependencyProvider: _namedDependencyProvider, loadContextFactory: runtimeApplicationHostContext.AssemblyLoadContextFactory); applicationHostContext.DependencyWalker.Walk(project.Name, project.Version, frameworkName); appHostContextCache[cacheKey] = applicationHostContext; } var libraryManager = applicationHostContext.LibraryManager; var metadataProvider = applicationHostContext.CreateInstance <ProjectMetadataProvider>(); var frameworkResolver = applicationHostContext.FrameworkReferenceResolver; var metadata = metadataProvider.GetProjectMetadata(project.Name); var dependencies = applicationHostContext.DependencyWalker .Libraries .Select(CreateDependencyDescription) .ToDictionary(d => d.Name); var projectReferences = applicationHostContext.DependencyWalker .Libraries .Where(d => string.Equals(d.Type, "Project") && !string.Equals(d.Identity.Name, project.Name)) .Select(d => new ProjectReference { Framework = new FrameworkData { ShortName = VersionUtility.GetShortFrameworkName(d.Framework), FrameworkName = d.Framework.ToString(), FriendlyName = frameworkResolver.GetFriendlyFrameworkName(d.Framework) }, Path = d.Path }) .ToList(); var frameworkData = new FrameworkData { ShortName = VersionUtility.GetShortFrameworkName(frameworkName), FrameworkName = frameworkName.ToString(), FriendlyName = frameworkResolver.GetFriendlyFrameworkName(frameworkName), RedistListPath = frameworkResolver.GetFrameworkRedistListPath(frameworkName) }; state.Frameworks.Add(frameworkData); var projectInfo = new ProjectInfo() { Path = appPath, Configuration = configuration, TargetFramework = frameworkData, FrameworkName = frameworkName, // TODO: This shouldn't be roslyn specific compilation options CompilationSettings = project.GetCompilationSettings(frameworkName, configuration), Dependencies = dependencies, ProjectReferences = projectReferences, Metadata = metadata, Output = new ProjectOutput() }; var export = libraryManager.GetLibraryExport(project.Name); var projectReference = export.MetadataReferences.OfType <IMetadataProjectReference>() .First(); var embeddedReferences = export.MetadataReferences.OfType <IMetadataEmbeddedReference>().Select(r => { return(new { Name = r.Name, Bytes = r.Contents }); }) .ToDictionary(a => a.Name, a => a.Bytes); var engine = new NonLoadingLoadContext(); if (!metadata.Errors.Any()) { projectReference.Load(engine); } projectInfo.Output.AssemblyBytes = engine.AssemblyBytes ?? new byte[0]; projectInfo.Output.PdbBytes = engine.PdbBytes ?? new byte[0]; projectInfo.Output.AssemblyPath = engine.AssemblyPath; projectInfo.Output.EmbeddedReferences = embeddedReferences; state.Projects.Add(projectInfo); if (state.ProjectSearchPaths == null) { state.ProjectSearchPaths = applicationHostContext.ProjectResolver.SearchPaths.ToList(); } if (state.GlobalJsonPath == null) { GlobalSettings settings; if (GlobalSettings.TryGetGlobalSettings(applicationHostContext.RootDirectory, out settings)) { state.GlobalJsonPath = settings.FilePath; } } } return(state); }
private bool DoStageTwo() { bool calculateDiagnostics = _requiresCompilation.WasAssigned; if (calculateDiagnostics) { _requiresCompilation.ClearAssigned(); } foreach (var pair in _local.Projects) { var project = pair.Value; var projectCompilationChanged = false; ProjectCompilation compilation = null; if (calculateDiagnostics) { projectCompilationChanged = UpdateProjectCompilation(project, out compilation); project.Diagnostics = new DiagnosticsMessage { Framework = project.Sources.Framework, Errors = compilation.Errors, Warnings = compilation.Warnings }; } Trigger <Void> requiresAssemblies; if ((_requiresAssemblies.TryGetValue(pair.Key, out requiresAssemblies) && requiresAssemblies.WasAssigned)) { requiresAssemblies.ClearAssigned(); // If we didn't already update the compilation then do it on demand if (compilation == null) { projectCompilationChanged = UpdateProjectCompilation(project, out compilation); } // Only emit the assembly if there are no errors and // this is the very first time or there were changes if (!compilation.Errors.Any() && (!compilation.HasOutputs || projectCompilationChanged)) { var engine = new NonLoadingLoadContext(); compilation.ProjectReference.Load(engine); compilation.AssemblyBytes = engine.AssemblyBytes ?? new byte[0]; compilation.PdbBytes = engine.PdbBytes ?? new byte[0]; compilation.AssemblyPath = engine.AssemblyPath; } project.Outputs = new OutputsMessage { FrameworkData = project.Sources.Framework, AssemblyBytes = compilation.AssemblyBytes ?? new byte[0], PdbBytes = compilation.PdbBytes ?? new byte[0], AssemblyPath = compilation.AssemblyPath, EmbeddedReferences = compilation.EmbeddedReferences }; if (project.Diagnostics == null) { project.Diagnostics = new DiagnosticsMessage { Framework = project.Sources.Framework, Errors = compilation.Errors, Warnings = compilation.Warnings }; } } } return(true); }