I'm working on a project where I compile projects from a solution using Roslyn.
foreach (var projectId in solution.GetProjectDependencyGraph().GetTopologicallySortedProjects())
{
var project = solution.GetProject(projectId);
var compilation = project.GetCompilationAsync().Result;
var errors = compilation.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error);
// ...
Compilation contains errors such as
error CS0012: The type 'Task' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Threading.Tasks, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Why Roslyn won't accept an existing reference to mscorlib?
Are there some CompilationOptions
that I should consider?
Per this thread I tried assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default
but it didn't help. I tried to work with metadataReferenceResolver
but couldn't find much information about it.
Following the solution in Roslyn has no reference to System.Runtime I implemented code that ensures that a project has references to mscorlib.dll, System.Core.dll, System.dll and System.Runtime.dll, such that my project and compilation have the references:
Side note: Reference #7 has been added this way. The project already had references #1, 2 and 3, and removing them and replacing with ones from C:\Windows\Microsoft.NET\Framework didn't solve the issue.
project.MetadataReferences.ToList()
Count = 8
[0]: Assembly Path='C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll'
[1]: Assembly Path='C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll'
[2]: Assembly Path='C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Core.dll'
[3]: Assembly Path='C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll'
[4]: Assembly Path='C:\Users\Amadeus\Documents\GitHub\InterProcessQueue\src\MemoryMappedQueue\packages\xunit.runner.visualstudio.2.0.0-rc1-build1030\build\_common\xunit.abstractions.dll'
[5]: Assembly Path='C:\Users\Amadeus\Documents\GitHub\InterProcessQueue\src\MemoryMappedQueue\packages\xunit.assert.2.0.0-rc1-build2826\lib\portable-net45+aspnetcore50+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll'
[6]: Assembly Path='C:\Users\Amadeus\Documents\GitHub\InterProcessQueue\src\MemoryMappedQueue\packages\xunit.extensibility.core.2.0.0-rc1-build2826\lib\portable-net45+aspnetcore50+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll'
[7]: Assembly Path='C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.dll'
compilation.ExternalReferences.ToList()
Count = 9
[0]: Assembly Path='C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll'
[1]: Assembly Path='C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll'
[2]: Assembly Path='C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Core.dll'
[3]: Assembly Path='C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll'
[4]: Assembly Path='C:\Users\Amadeus\Documents\GitHub\InterProcessQueue\src\MemoryMappedQueue\packages\xunit.runner.visualstudio.2.0.0-rc1-build1030\build\_common\xunit.abstractions.dll'
[5]: Assembly Path='C:\Users\Amadeus\Documents\GitHub\InterProcessQueue\src\MemoryMappedQueue\packages\xunit.assert.2.0.0-rc1-build2826\lib\portable-net45+aspnetcore50+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll'
[6]: Assembly Path='C:\Users\Amadeus\Documents\GitHub\InterProcessQueue\src\MemoryMappedQueue\packages\xunit.extensibility.core.2.0.0-rc1-build2826\lib\portable-net45+aspnetcore50+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll'
[7]: Assembly Path='C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.dll'
[8]: Compilation (C#): MemoryMappedQueue
CompilationOptions
I should use?Given a mscorlib that is a suitable reference assembly it will compile just fine. The root problem here is that mscorlib, on Net Core, is not a stand alone reference library. That part is "By Design". That's not a decision that roslyn controls though.
Also the actual mscorlib which contains Object (lets call it System.Private.Corlib) isn't usable as a reference library. It has a number of inconsistencies and duplicate types that make it unsuitable as a reference assembly.
Referencing a PCL library with Roslyn results in .NET version issues 6 Generate C# code with Roslyn and .NET Core 4 Automatically resolving dependencies when compiling using Roslyn 7 How to write a roslyn analyzer that references a dotnet standard 2.0 project 2
You should follow what Razor views in ASP.NET Core are doing. Require the developer to produce a set of reference assemblies that you can use at runtime to pass to Roslyn as references. I am doing a similar dynamic compilation to the above code in an Class Library project, which has its target frameworks defined as:
As per Kevin's answer, this can be resolved by specifying a property for MSBuildWorkspace
:
var props = new Dictionary<string, string>();
props["CheckForSystemRuntimeDependency"] = "true";
var msWorkspace = MSBuildWorkspace.Create(props);
Now solutions opened in msWorkspace
will correctly resolve their references.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With