使用我的 NuGet 包编译项目的 .bond 文件

Compile .bond files of projects using my NuGet package

我有一个带有 .bond 文件的 NuGet 包。我的包的用户可以从我的包的 .bond 文件中的结构派生他们的 Bond 结构。

我希望用户的 Bond 文件在包含我的 NuGet 包时被编译。今天他们必须包括我的 NuGet 和 Bond.CSharp NuGet。但是,我的 NuGet 已经引用了 Bond.CSharp.

我如何编写我的包以便消费者不需要拥有自己的包<PackageReference Include="Bond.CSharp" ... />

Bond codegen 是 运行 来自 Bond.CSharp 的构建目标。

默认情况下,您使用的包的构建目标不会流向您的消费者。 PackageReferencePrivateAssets 的默认值是 "contentfiles;analyzers;build".

您可以在 csproj 的 PackageReference:

中覆盖此行为
<ItemGroup>
  <PackageReference Include="Bond.CSharp" Version="[9.0.3]">
    <!-- removing "build" from default so that consumers also run codegen -->
    <PrivateAssets>contentfiles;analyzers</PrivateAssets>
  </PackageReference>
</ItemGroup>

我假设您正在将基本结构编译到包中的程序集中。 Bond codegen 假定生成的代码和 运行time 库完全匹配,所以我使用了在 PackageReference 中绑定的完全匹配版本:[9.0.3]

您说过您希望您的消费者能够从您的 Bond 结构派生,因此您可能还想配置他们的 BondImportPath 以将 .bond 文件包含在您的包中。为此,您需要

  1. 确保 .bond 文件包含在包中并且
  2. 添加一个包 .props 文件以将 BondImportPath 设置为包含所述 .bond 文件的包目录。

确保 .bond 文件包含在包中,将类似这样的内容添加到包的 .csproj 文件中:

<ItemGroup>
  <None Include="bond/**">
    <Pack>true</Pack>
    <PackagePath>build/bond/</PackagePath>
  </None>
</ItemGroup>

这假定您的 .bond 文件位于 bond\ 子目录中。

要自动向 BondImportPath 添加内容,您需要添加一个包 .props 文件,该文件将由消费者自动导入。创建一个名为 <i>ExactNameOfPackage</i>.props 的文件,内容如下:

<Project>
  <ItemGroup>
    <BondImportDirectory Include="$(MSBuildThisFileDirectory)bond" />
  </ItemGroup>
</Project>

这个.props文件也需要打包。将此添加到项目的 .csproj 文件中:

<ItemGroup>
  <None Include="ExactNameOfPackage.props">
    <Pack>true</Pack>
    <PackagePath>build/</PackagePath>
  </None>
</ItemGroup>

现在,消费者只需使用 PackageReference。他们项目中的任何 .bond 文件都会自动编译,他们可以使用 import "you-file.bond" 来引用您的包中的 .bond 文件。

构建资产不会自然流动 运行。 NuGet 5+ buildTransitive feature 看起来可以解决这个问题,但我还没有试验过。


这是我使用的完整项目文件。完整的代码在我的 GitHub 存储库中,export-bond-file-nuget.

lib-with-bond.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <PackageId>LibWithBond</PackageId>
    <Version>1.2.0</Version>
  </PropertyGroup>

  <ItemGroup>
    <None Include="LibWithBond.props">
      <Pack>true</Pack>
      <PackagePath>build/</PackagePath>
    </None>
    <None Include="bond/**">
      <Pack>true</Pack>
      <PackagePath>build/bond/</PackagePath>
    </None>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Bond.CSharp" Version="[9.0.3]">
      <PrivateAssets>contentfiles;analyzers</PrivateAssets>
    </PackageReference>
  </ItemGroup>
</Project>

LibWithBond.props

<Project>
  <ItemGroup>
    <BondImportDirectory Include="$(MSBuildThisFileDirectory)bond" />
  </ItemGroup>
</Project>

消耗-lib.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <!-- I had a local NuGet source pointing to the output of running
    `dotnet pack` on lib-with-bond.csproj -->
    <PackageReference Include="LibWithBond" Version="1.2.0" />
  </ItemGroup>
</Project>

我能够为 PackageReference 完成这项工作。我最初的实验使其适用于 ProjectReference 没有成功,我 运行 没有时间在这个答案上做更多的工作。