Migrating a solution from .NET Core 3.1 to .NET 5.0 fail on CSharpCompilation emit. I was able to reproduce the problem with a minimal project as described on the steps bellow.
Version Used: Microsoft.CodeAnalysis.CSharp (3.8.0)
Steps to Reproduce:
class Program
{
static void Main(string[] args)
{
string testClass = "" +
"using System;" +
"public class TesteClass" +
"{" +
"public TesteClass()" +
"{" +
"var obj = new Object();" +
"Console.WriteLine(obj);" +
"}" +
"}";
var references = new List<MetadataReference>
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Console).Assembly.Location),
MetadataReference.CreateFromFile(typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Assembly.Location),
};
var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString() + ".dll")
.WithOptions(new CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary))
.AddReferences(references)
.AddSyntaxTrees(CSharpSyntaxTree.ParseText(testClass));
var eResult = compilation.Emit("test.dll");
Console.ReadLine();
}
}
Expected Behavior:
Success: true, same result as dotnet core 3.1
Actual Behavior:
error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
I have the same problem
This behavior is "By Design". The problem here is that the technique you are using here to add references is using implementation assemblies, not reference assemblies. The stability of APIs in implementation assemblies is not guaranteed over time. The solution here is to reference the reference assemblies in the project.
Unfortunately it's not as easy to reference them, they don't have the handy typeof(object).Assembly.Location
expression. It requires a bit of work to package them with your application to be usable. The following project has a base implementation of packaging these references that you can look at for an approach here.
Yes, it solved.
Thank you
@robertsabo0 - how did you solve it?
@tkw-devs you can solve using this marked code:
@tkw-devs - got it 馃憤 I manage to solve it! Thx!
@jaredpar The example I gave works perfectly in the .net core, when upgrading to .net 5 it stops working, having to be implemented the way it was done, I still think it should work as it did before, imagine there each dotnet version as previous things stop working and you have to rewrite again?
@tkw-devs I downloaded the repository on link that @jaredpar sent: https://github.com/jaredpar/roslyn-codedom
Here, you have powershell script named: Generate.ps1 .
I edited it to add .NET 5.0
At about line 100, calls of Add-TargetFramework looks like this:
Add-TargetFramework "NetCoreApp31" 'Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1'
Add-TargetFramework "Net50" 'Microsoft.NETCore.App.Ref\5.0.0\ref\net5.0'
Add-TargetFramework "NetStandard20" 'netstandard.library\2.0.0\build\netstandard2.0\ref'
After running script, I included that project to my solution as dependency and to all references collection when compiling I added Net50.All
I hope I helped you :)
this is works the key is:
Assembly.GetEntryAssembly().GetReferencedAssemblies()
.ToList()
.ForEach(a => references.Add(MetadataReference.CreateFromFile(Assembly.Load(a).Location)));
@Mun1z
The example I gave works perfectly in the .net core, when upgrading to .net 5 it stops working, having to be implemented the way it was done, I still think it should work as it did before, imagine there each dotnet version as previous things stop working and you have to rewrite again?
The problem here is that your sample referenced the implementation assemblies and that is officially not supported by the runtime team. The are free to refactor the implementation assemblies as they choose. In this case that resulted in a new assembly that you're not referencing here that is necessary for a successful compilation in .NET 5. Using the reference assemblies though means you'll get a consistent experience between .NET Core versions.
To be clear this is not something the compiler controls. The compiler is working with the inputs its given here and in this case there aren't sufficient references for us to run a compilation.
Most helpful comment
this is works the key is: