0

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

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

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

4

1 回答 1

1

Bond 代码生成是从 Bond.CSharp 的构建目标运行的。

默认情况下,您使用的包的构建目标不会流向您的消费者。PackageReferencea的PrivateAssets默认值为"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 假设生成的代码和运行时库完全匹配,所以我使用了一个完全匹配的版本,绑定在PackageReference[9.0.3]

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

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

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

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

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

要自动向BondImportPath.props 添加内容,您需要添加一个包 .props 文件,该文件将由消费者自动导入。创建一个包含ExactNameOfPackage.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 功能看起来可以解决这个问题,但我还没有尝试过。


这是我使用的完整项目文件。完整的代码在我的 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没有成功,我没有时间在这个答案上做更多的工作。

于 2021-02-05T19:56:18.057 回答