Originally I wrote multiple code generators (need netstandard2.0), and wanted to extract common functionalities into a library (also netstandard2.0). However, when trying to reference the library I always get an error that the .dll file was not found, even though it is there. I spent 3 hours browsing the web and debugging and below you find a MRE. I'm not yet exactly sure that it is the exact same problem I'm facing, since it's complaining about Microsoft's dll and not my own, but I still hope this fix to this will also be a fix to my problem. I'm aware that a newer version of the package is available, but I couldn't get the code generator to run with a newer version, so I'm sticking to this one.
How can I get this running?
In VS 17.9.3, create a new Console Application, TargetFramework net8.0.
In the same solution, add a new Library project, TargetFramework netstandard2.0.
MyLib.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" PrivateAssets="all" />
</ItemGroup>
</Project>
Class1.cs
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace MyLib
{
public class Class1
{
public int GetNumber()
{
AttributeSyntax node = null;
return 1337;
}
}
}
In the same solution, add a second new library project, TargetFramework netstandard2.0:
MySecondLib.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MyLib\MyLib.csproj" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" PrivateAssets="all" />
</ItemGroup>
</Project>
Class2.cs
using Microsoft.CodeAnalysis.CSharp.Syntax;
using MyLib;
using System;
namespace MySecondLib
{
public class Class2 : Class1
{
public void PrintNumber()
{
AttributeSyntax node = null;
Console.WriteLine(GetNumber());
}
}
}
For the original console Application, use the following file: NetStandardReproduction.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MySecondLib\MySecondLib.csproj" />
</ItemGroup>
</Project>
Program.cs
using MySecondLib;
namespace NetStandardReproduction
{
internal class Program
{
static void Main(string[] args)
{
var obj = new Class2();
obj.PrintNumber();
}
}
}
It will build fine, but when you run it it fails with an unhandle Exception:
System.IO.FileNotFoundException: 'Could not load file or assembly 'Microsoft.CodeAnalysis.CSharp, Version=4.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.'
If you remove the reference from both packages and comment the lines with AttributeSyntax
it works just fine.
Check out the Controlling dependency assets (and Use functionality from NuGet packages section of the Source Generators Cookbook):
You might be using a dependency purely as a development harness and might not want to expose that to projects that will consume your package. In this scenario, you can use the
PrivateAssets
metadata to control this behavior.
Basically PrivateAssets=all
means that the consumers of this library will not reference dependency marked with it, hence the final console app will not have Microsoft.CodeAnalysis.CSharp
referenced, hence error.
Either remove/modify PrivateAssets
property in the libraries or add the Microsoft.CodeAnalysis.CSharp
as an explicit dependency to the final app:
<ItemGroup>
<ProjectReference Include="..\MySecondLib\MySecondLib.csproj"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
</ItemGroup>