Background

最初,我编写了多个代码生成器(需要netStandard2.0),并希望将常见功能提取到一个库中(也需要netStandard2.0).然而,当try 引用库时,我总是得到一个错误,即找不到.dll文件,即使它在那里.我花了3个小时浏览网页和调试,在下面你可以找到一个MRE.我还不确定这是不是我面临的完全相同的问题,因为它抱怨的是微软的DLL,而不是我自己的,但我仍然希望这个修复程序也能修复我的问题.我知道有较新版本的包可用,但我无法让代码生成器与较新版本一起运行,因此我坚持使用此版本.

Question

我怎么才能让它运行起来?

Steps to reproduce:

在VS 17.9.3中,创建一个新的控制台应用程序TargetFrameworknet8.0.

在同一个解决方案中,添加一个新的Library项目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;
        }
    }
}

在同一个解决方案中,添加第二个新的库项目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());
        }
    }
}

对于原始控制台应用程序,请使用以下文件: 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();
        }
    }
}

它可以很好地构建,但当您运行它时,它会失败,并出现UnHandle异常:

System. IO. FileNotFoundException:"无法加载文件或程序集"Microsoft. CodeAnalysis. CSharp,Version = 4.7.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35 ".系统找不到指定的文件."

如果你从两个包中删除引用,并用AttributeSyntax注释行,它就可以正常工作了.

推荐答案

查看源代码生成器指南的Controlling dependency assets(和Use functionality from NuGet packages)部分:

您可能纯粹将依赖项用作开发工具,并且可能不希望将其公开给将使用您的包的项目.在这种情况下,您可以使用PrivateAssets个元数据来控制此行为.

基本上,PrivateAssets=all意味着这个库的使用者不会引用标记了它的依赖项,因此最终的控制台应用程序不会引用Microsoft.CodeAnalysis.CSharp,因此是错误的.

删除/修改库中的PrivateAssets属性,或者将Microsoft.CodeAnalysis.CSharp作为一个显式依赖项添加到最终应用中:

<ItemGroup>
    <ProjectReference Include="..\MySecondLib\MySecondLib.csproj"/>
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
</ItemGroup>

Csharp相关问答推荐

.NET通过版本自动增量设置包版本

无法更改或使用C#(WinForms.NET)中的全局变量

发布.NET框架项目将.NET核心元素注入到web. connect中

在C# 11之前, struct 中的每个字段都必须显式分配?不能繁殖

Regex在c#中完全匹配

获取ASP.NET核心身份认证cookie名称

C#.NET依赖项注入顺序澄清

返回TyedResults.BadRequest<;字符串>;时问题详细信息不起作用

XUNIT是否使用测试数据的源生成器?

创建临时Collection 最有效的方法是什么?堆栈分配和集合表达式之间的区别?

如何使用新的Microsoft.IdentityModel.JsonWebToken创建JwtSecurityToken?

注册所有IMediatR类

Rx.Net窗口内部可观测数据提前完成

由于POST中的应用程序/JWT,出现不支持的内容类型异常

显示文档的ECDsa签名PDF在Adobe Reader中签名后已被更改或损坏

如果设置了另一个属性,则Newtonsoft JSON忽略属性

该函数不能检测两条曲线的交点

如何在Cake脚本中设置MSBuild.exe的绝对路径

用于分钟和秒验证的MudTextfield的正则表达式掩码

.NET6最小API:操作.MapGet之后的响应