Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Roslyn compilation doesn't resolve mscorlib references

Tags:

c#

roslyn

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?

  • msdn for System.Threading.Task points out that this type is indeed located in mscorlib.dll
  • PublicKeyToken b03f5f7f11d50a3a matches mscorlib's

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
  • How can I get Roslyn to compile this project?
  • Are there any CompilationOptions I should use?
  • Is Roslyn's issue #970 related to this?
like image 486
Amadeusz Wieczorek Avatar asked Apr 08 '15 19:04

Amadeusz Wieczorek


People also ask

Why can't Roslyn compile mscorlib?

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.

Why is mscorlib not used as a reference library?

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.

Can I reference a PCL library with Roslyn?

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

How can I Pass razor views to Roslyn?

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:


1 Answers

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.

like image 124
Amadeusz Wieczorek Avatar answered Sep 28 '22 19:09

Amadeusz Wieczorek