public ProjectContext CreateContext(ProjectConfiguration projectConfig, bool restore = false) { var context = new RoslynProjectContext(projectConfig); var builder = new MsBuildProjectContextBuilder(Logger, context); if (restore) { builder = builder.RestoreProjectPackages(); } context.MsBuildProjectContext = builder.BuildProjectContext(); return(context); }
/* * This is currently quite flawed - getting missing method exceptions for methods that clearly exist * when trying to instantiate types in the loaded assembly. * The intent behind this was to instantiate the DbContext to get EF's model metadata and use that * for code generation, since its going to be more correct & consistent than our guesses about the data model. * * public Assembly GetAssembly() * { * //return null; * var projectFileName = Path.GetFileName(_projectContext.ProjectFilePath); * var project = _projectWorkspace.CurrentSolution.Projects * .SingleOrDefault(p => Path.GetFileName(p.FilePath) == projectFileName); * * using (var assemblyStream = new MemoryStream()) * { * using (var pdbStream = new MemoryStream()) * { * var result = GetProjectCompilation().Emit( * assemblyStream, * pdbStream); * * if (!result.Success) * { * throw new TypeLoadException($"Couldn't emit assembly for project {_projectContext.ProjectFilePath}"); * } * * assemblyStream.Seek(0, SeekOrigin.Begin); * pdbStream.Seek(0, SeekOrigin.Begin); * * //var domain = AppDomain.CreateDomain($"{_projectContext.ProjectFilePath}-compilation"); * //domain.ExecuteAssembly(project.OutputFilePath); * //foreach (var file in _projectContext.CompilationAssemblies) * //{ * // try * // { * // domain.Load(AssemblyName.GetAssemblyName(file.ResolvedPath)); * // } * // catch { } * //} * * AppDomain.CurrentDomain.AssemblyLoad += (sender, args) => Console.WriteLine(args.LoadedAssembly.ToString()); * * AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => * { * var name = new AssemblyName(args.Name); * var match = _projectContext.CompilationAssemblies.FirstOrDefault(a => AssemblyName.GetAssemblyName(a.ResolvedPath).Name == name.Name); * if (match != null) * { * return Assembly.LoadFrom(match.ResolvedPath); * } * return null; * }; * * var assembly = Assembly.Load(assemblyStream.ToArray(), pdbStream.ToArray()); * //var assembly = Assembly.LoadFrom(project.OutputFilePath); * var contextType = assembly.GetType("Intellitect.Myriad.Data.AppDbContext"); * var instance = Activator.CreateInstance(contextType); * * return assembly; * } * } * } */ public static RoslynTypeLocator FromProjectContext(RoslynProjectContext project) { var workspace = new RoslynWorkspace(project.MsBuildProjectContext, project.MsBuildProjectContext.Configuration); workspace.WorkspaceFailed += (object sender, WorkspaceDiagnosticEventArgs e) => { if (e.Diagnostic.Kind == WorkspaceDiagnosticKind.Failure) { // NB: Ultimately an InvalidCast happens with the TypeScript FindConfigFilesTask (compiled // against v4.0 of Microsoft.Build) trying to cast to a ITask in Microsoft.Build v15.0 // Therefore we must ignore an empty error message. Debug.WriteLine(e.Diagnostic.Message); if (!e.Diagnostic.Message.Contains( "Unable to cast object of type 'Microsoft.CodeAnalysis.BuildTasks.Csc' to type 'Microsoft.Build.Framework.ITask'.")) { throw new InvalidProjectFileException(e.Diagnostic.Message); } } }; return(new RoslynTypeLocator(workspace, project)); }
public RoslynTypeLocator(Workspace projectWorkspace, RoslynProjectContext projectContext) { _projectWorkspace = projectWorkspace ?? throw new ArgumentNullException(nameof(projectWorkspace)); _projectContext = projectContext; }