1818using Microsoft . VisualStudio . Threading ;
1919using CodeConv . Shared . Util ;
2020using System . ComponentModel . DataAnnotations ;
21+ using Microsoft . CodeAnalysis . Host . Mef ;
2122
2223namespace ICSharpCode . CodeConverter . CommandLine
2324{
@@ -26,7 +27,7 @@ public sealed class MSBuildWorkspaceConverter : IDisposable
2627 private readonly bool _bestEffortConversion ;
2728 private readonly string _solutionFilePath ;
2829 private readonly Dictionary < string , string > _buildProps ;
29- private readonly Lazy < MSBuildWorkspace > _workspace ; //Cached to avoid NullRef from OptionsService when initialized concurrently (e.g. in our tests)
30+ private readonly AsyncLazy < MSBuildWorkspace > _workspace ; //Cached to avoid NullRef from OptionsService when initialized concurrently (e.g. in our tests)
3031 private AsyncLazy < Solution > ? _cachedSolution ; //Cached for performance of tests
3132 private readonly bool _isNetCore ;
3233
@@ -38,7 +39,7 @@ public MSBuildWorkspaceConverter(string solutionFilePath, bool isNetCore, bool b
3839 _buildProps . TryAdd ( "Platform" , "AnyCPU" ) ;
3940 _solutionFilePath = solutionFilePath ;
4041 _isNetCore = isNetCore ;
41- _workspace = new Lazy < MSBuildWorkspace > ( ( ) => CreateWorkspace ( _buildProps ) ) ;
42+ _workspace = new AsyncLazy < MSBuildWorkspace > ( ( ) => CreateWorkspaceAsync ( _buildProps ) ) ;
4243 }
4344
4445 public async IAsyncEnumerable < ConversionResult > ConvertProjectsWhereAsync ( Func < Project , bool > shouldConvertProject , Language ? targetLanguage , IProgress < ConversionProgress > progress , [ EnumeratorCancellation ] CancellationToken token )
@@ -70,7 +71,7 @@ private async Task<Solution> GetSolutionAsync(string projectOrSolutionFile, IPro
7071 progress . Report ( $ "Running dotnet restore on { projectOrSolutionFile } ") ;
7172 await RestorePackagesForSolutionAsync ( projectOrSolutionFile ) ;
7273
73- var workspace = _workspace . Value ;
74+ var workspace = await _workspace . GetValueAsync ( ) ;
7475 var solution = string . Equals ( Path . GetExtension ( projectOrSolutionFile ) , ".sln" , StringComparison . OrdinalIgnoreCase ) ? await workspace . OpenSolutionAsync ( projectOrSolutionFile )
7576 : ( await workspace . OpenProjectAsync ( projectOrSolutionFile ) ) . Solution ;
7677
@@ -95,7 +96,7 @@ private async Task<Solution> GetSolutionAsync(string projectOrSolutionFile, IPro
9596 private async Task < string > GetCompilationErrorsAsync (
9697 IEnumerable < Project > projectsToConvert )
9798 {
98- var workspaceErrors = _workspace . Value . Diagnostics . GetErrorString ( ) ;
99+ var workspaceErrors = ( await _workspace . GetValueAsync ( ) ) . Diagnostics . GetErrorString ( ) ;
99100 var errors = await projectsToConvert . ParallelSelectAwait ( async x => {
100101 var c = await x . GetCompilationAsync ( ) ?? throw new InvalidOperationException ( $ "Compilation could not be created for { x . Language } ") ;
101102 return new [ ] { CompilationWarnings . WarningsForCompilation ( c , c . AssemblyName ) } ;
@@ -110,7 +111,7 @@ private static async Task RestorePackagesForSolutionAsync(string solutionFile)
110111 if ( restoreExitCode != 0 ) throw new ValidationException ( "dotnet restore had a non-zero exit code." ) ;
111112 }
112113
113- private static MSBuildWorkspace CreateWorkspace ( Dictionary < string , string > buildProps )
114+ private static async Task < MSBuildWorkspace > CreateWorkspaceAsync ( Dictionary < string , string > buildProps )
114115 {
115116 if ( MSBuildLocator . CanRegister ) {
116117 var instances = MSBuildLocator . QueryVisualStudioInstances ( ) . ToArray ( ) ;
@@ -119,12 +120,14 @@ private static MSBuildWorkspace CreateWorkspace(Dictionary<string, string> build
119120 MSBuildLocator . RegisterInstance ( instance ) ;
120121 AppDomain . CurrentDomain . UseVersionAgnosticAssemblyResolution ( ) ;
121122 }
122- return MSBuildWorkspace . Create ( buildProps , ThreadSafeWorkspaceHelper . HostServices ) ;
123+
124+ var hostServices = await ThreadSafeWorkspaceHelper . CreateHostServicesAsync ( MSBuildMefHostServices . DefaultAssemblies ) ;
125+ return MSBuildWorkspace . Create ( buildProps , hostServices ) ;
123126 }
124127
125128 public void Dispose ( )
126129 {
127- if ( _workspace . IsValueCreated ) _workspace . Value . Dispose ( ) ;
130+ if ( _workspace . IsValueCreated ) _workspace . GetValueAsync ( ) . Dispose ( ) ;
128131 }
129132 }
130133}
0 commit comments