如何以安装我们的项目 dll 然后单独安装 3rd 方 nuget 包的方式打包 nuget 包

How to pack nuget package in such a way that it install our project dlls and then install 3rd party nuget packages separately

我有一个 dotnet 解决方案,它包含许多 .NET Framework 4.8 class 库项目。一些项目安装了其他包,如 log4net、Oracle.ManagedDataAccess、GraphQL.Client。在此解决方案文件中,我有一个基础 NET Framework 4.8 class 库项目,我已将所有其他 class 库作为依赖项添加到该项目中。

现在我使用 azurepipelines.yml 构建整个解决方案并打包基础项目并将其作为 nuget 包推送。现在我的 nuget 包有所有的 dll 加上它有 log4net 的 dll 和我安装到我的项目的其他 nuget 包。所以这个包的体积非常大。相反,我只想要我的项目 dll 和 Microsoft dll,而不是我的 nuget 包中的第三方包。当我在其他解决方案中安装此 nuget 包时,我希望将其他库(log4net、Oracle.ManagedDataAccess、GraphQL.Client)与其一起安装到“packages”文件夹中。

这将帮助我获得一个小的 nuget 包,这些额外的库 dll 将单独安装。我该怎么做?

- task: DotNetCoreCLI@2
  displayName: 'Dotnet Pack'
  inputs:
    command: 'pack'
    arguments: '--configuration $(buildConfiguration)'
    packagesToPack: '**/MyBaseProject.csproj'
    versioningScheme: 'off'
    includeReferencedProjects: true

- task: NuGetCommand@2
  displayName: 'NuGet Push'
  inputs:
    command: 'push'
    feedsToUse: 'select'
    packagesToPush: '$(Build.ArtifactStagingDirectory)/**/XX*.nupkg'
    versioningScheme: 'off'
    allowPackageConflicts: true
    publishVstsFeed: 'feedIDHere'

我的csproj如下图

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <PackageId>MyPackage</PackageId>
    <Version>1.1.10</Version>
</PropertyGroup>

<ItemGroup>
    <ProjectReference Include="..\Business\xx1.csproj">
       <ExcludeAssets>all</ExcludeAssets>
    </ProjectReference></ProjectReference>
    <ProjectReference Include="..\Logging\xx2.csproj">
       <ExcludeAssets>all</ExcludeAssets>
    </ProjectReference></ProjectReference>
    <ProjectReference Include="..\Services\xx3.csproj">
       <ExcludeAssets>all</ExcludeAssets>
    </ProjectReference></ProjectReference>
</ItemGroup>
<ItemGroup>
   <None Include="..\Business\bin$(Configuration)\*.dll">
      <PackagePath>lib\net48</PackagePath>
      <Pack>true</Pack>
      <Visible>false</Visible>
   </None>
</ItemGroup>
</Project>

更新:

What I'm lokking for is that I don't want any 3rd party dlls (like Oracle.ManagedDataAcess or GraphQL) to come inside my nupkg, rather I want them to be installed separately when I install my nupkg in other projects using Visual Studio Nuget Package Manager. Can this be done?

答案是肯定的。

如果您不想在您的 nupkg 中包含任何第 3 方 dll,您可以将这些包安装到基础 NET Framework 4.8 class 库项目中,而不是添加 dll 文件:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <PackageId>MyPackage</PackageId>
    <Version>2.1.10</Version>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="GraphQL" Version="4.5.0" />
    <PackageReference Include="Oracle.ManagedDataAccess" Version="19.11.0" />
  </ItemGroup>

<ItemGroup>
    <ProjectReference Include="..\Business\xx1.csproj">
       <ExcludeAssets>all</ExcludeAssets>
    </ProjectReference></ProjectReference>
    <ProjectReference Include="..\Logging\xx2.csproj">
       <ExcludeAssets>all</ExcludeAssets>
    </ProjectReference></ProjectReference>
    <ProjectReference Include="..\Services\xx3.csproj">
       <ExcludeAssets>all</ExcludeAssets>
    </ProjectReference></ProjectReference>
</ItemGroup>
<ItemGroup>
   <None Include="..\Business\bin$(Configuration)\*.dll">
      <PackagePath>lib\net48</PackagePath>
      <Pack>true</Pack>
      <Visible>false</Visible>
   </None>
</ItemGroup>
</Project>

然后我们使用这个项目的dotnet pack,我们将得到那些包作为依赖的包:

当我使用 Visual Studio Nuget 包管理器

在其他项目中安装我的 nupkg 时,将单独安装这些依赖项

How to pack nuget package in such a way that it install our project dlls and then install 3rd party nuget packages separately

您可以使用 .nupsec 文件将这些库添加到 tools 文件夹中,这将在我们安装基础 NET Framework 4.8 class 库包后将这些库保存在 packages 文件夹中。

我们需要使用工具约定创建一个 .nupsec:

  <files>
    <file src="bin\Debug\YourBase.dll" target="lib\net48" />
    <file src="Business\bin$(Configuration)\*.dll" target="Tools\libraries"/>
  </files> 

您可以查看此文档 Create the .nuspec file 了解更多详细信息。

此外,<Pack>true</Pack> 仅适用于 SDK 样式项目:

<ItemGroup>
   <None Include="..\Business\bin$(Configuration)\*.dll">
      <PackagePath>lib\net48</PackagePath>
      <Pack>true</Pack>
      <Visible>false</Visible>
   </None>
</ItemGroup>

注意:安装基础包后,这些库应该在 Packages 文件夹中的文件夹 Tools\libraries 下,而不是添加到项目中。

我通过添加 nuspec 文件并更改 dotnet pack 作业以查找 nuspec 来纠正问题。

- task:  DotNetCoreCLI@2
  displayName: 'Dotnet Pack'
  inputs:
    command: 'pack'
    arguments: '--configuration $(buildConfiguration)'
    packagesToPack: '**/Myprjoect.nuspec'
    versioningScheme: 'off'
    nobuild: true
    includeReferencedProjects: true

nuspec 文件如下所示。

<?xml version="1.0" encoding="utf-8"?>
<package>
  <metadata>
    <id>Package Name</id>
    <version>1.1.15</version>
    <dependencies>
      <group targetFramework=".NETFramework4.8">
        <dependency id="GraphQL.Client" version="3.2.0" />
        <dependency id="iTextSharp" version="5.5.9" />
        <dependency id="log4net" version="2.0.5" />
        <dependency id="Oracle.ManagedDataAccess" version="19.11.0" />
      </group>
    </dependencies>
  </metadata>
  <files>
    <file src="**\*.dll" exclude="**\GraphQL.*;**\Oracle*.dll;**\obj\**\*.*;**\itextsharp.dll;**\log4net.dll" target="lib\net48" />
  </files>
</package>

这些更改帮助我将 nuget 包的大小从 >10MB 减小到 <4MB。当我在 Visual Studio 中通过 Nuget 包管理器在其他解决方案中安装我的包时,依赖项会单独安装。