繁体   English   中英

创建 nuget package 而解决方案使用干净的架构

[英]Create nuget package while solution uses clean architecture

我有使用干净架构的解决方案,所以我有以下项目:

  1. Core
  2. 依赖CoreApplication
  3. 依赖ApplicationInfrastructure
  4. Web取决于ApplicationInfrastructure

我需要创建 NuGet package,所以我使用Web.csproj进入文件夹,并在 PowerShell 中键入以下命令: .\nuget pack Web/Web.csproj -IncludeReferencedProjects

似乎一切都应该工作,但是当我将这个 NuGet package 安装到另一个项目中时,我收到以下警告:

警告 NU1603 Web 1.0.0 依赖于基础设施 (>= 1.0.0) 但未找到基础设施 1.0.0。 Infrastructure 1.0.0.1 的近似最佳匹配已解决。

警告 NU1603 Web 1.0.0 取决于应用程序 (>= 1.0.0) 但未找到应用程序 1.0.0。 应用程序 1.2.1 的近似最佳匹配已解决。

警告 NU1701 Package 已使用“.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, . NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8, .NETFramework,Version=v4.8.1' 而不是项目目标框架 .net7.0'。 这个 package 可能与你的项目不完全兼容。

以上所有项目( CoreApplicationInfrastructureWeb )都使用.NET 7。我的 NuGet package 有什么问题? 我该如何解决?

这些是我的 current.csproj: Web.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <IsPackable>true</IsPackable>
        <Version>1.3.2</Version>
    </PropertyGroup>

    <ItemGroup>
        <ProjectReference Include="..\Application\Application.csproj" />
        <ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
    </ItemGroup>

</Project>

Application.csproj

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0" />
    <PackageReference Include="NSec.Cryptography" Version="22.4.0" />
    <PackageReference Include="Paseto.Core" Version="1.0.7" />
</ItemGroup>

<ItemGroup>
    <ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>

Infrastructure.csproj

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0" />
</ItemGroup>

<ItemGroup>
    <ProjectReference Include="..\Application\Application.csproj" />
</ItemGroup>

Core.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Base64-Url" Version="1.0.0" />
  </ItemGroup>

</Project>

从我一直在研究的内容来看,没有一个好的方法可以做到这一点。 但是,可以通过两种不同的方式绕过它。

1.编辑teneko 贴出的.csproj

你应该编辑.csproj在所有引用中添加PrivateAssets="All”并将<TargetsForTfmSpecificBuildOutput>添加到web.api ,然后是<target>块。

Web.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <IsPackable>true</IsPackable>
        <Version>1.3.2</Version>
    </PropertyGroup>

    <ItemGroup>
        <ProjectReference Include="..\Application\Application.csproj" PrivateAssets="All"/>
        <ProjectReference Include="..\Infrastructure\Infrastructure.csproj" PrivateAssets="All"/>
    </ItemGroup>

   <PropertyGroup>
        <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
    </PropertyGroup>
    <Target Name="CopyProjectReferencesToPackage" DependsOnTargets="BuildOnlySettings;ResolveReferences">
    <ItemGroup>
      <!-- Filter out unnecessary files -->
      <_ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference')->WithMetadataValue('PrivateAssets', 'All'))"/>
    </ItemGroup>

    <!-- Print batches for debug purposes -->
    <Message Text="Batch for .nupkg: ReferenceCopyLocalPaths = @(_ReferenceCopyLocalPaths), ReferenceCopyLocalPaths.DestinationSubDirectory = %(_ReferenceCopyLocalPaths.DestinationSubDirectory) Filename = %(_ReferenceCopyLocalPaths.Filename) Extension = %(_ReferenceCopyLocalPaths.Extension)" Importance="High" Condition="'@(_ReferenceCopyLocalPaths)' != ''" />

    <ItemGroup>
      <!-- Add file to package with consideration of sub folder. If empty, the root folder is chosen. -->
      <BuildOutputInPackage Include="@(_ReferenceCopyLocalPaths)" TargetPath="%(_ReferenceCopyLocalPaths.DestinationSubDirectory)"/>
    </ItemGroup>
  </Target>
</Project>

应用程序.csproj

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0" />
    <PackageReference Include="NSec.Cryptography" Version="22.4.0" />
    <PackageReference Include="Paseto.Core" Version="1.0.7" />
</ItemGroup>

<ItemGroup>
    <ProjectReference Include="..\Core\Core.csproj" PrivateAssets="All"/>
</ItemGroup>

基础设施.csproj

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0" />
</ItemGroup>

<ItemGroup>
    <ProjectReference Include="..\Application\Application.csproj" PrivateAssets="All"/>
</ItemGroup>

core.csproj 没有改变。

并应用命令do.net pack --output C:/MySampleApi -p:PackageVersion=1.3.2

此方法依赖于您编辑 .csproj,这可能会干扰测试引用。 我认为必须编辑有效的代码才能以不同的方式提供它是错误的。

2. nuspec 方法

您需要在/project/web文件夹中创建一个 nuspec 文件并添加<files>标记以将/bin/release中的 dll 添加到C:/users/<username>/.nuget/packages/<project-name>/<version>/lib.net7.0 (如果您使用的是 Windows),nuspec 文件应如下所示。

web.nuspec(你可以在C:/users/<username>/.nuget/packages/<project-name>/<existing-version>中找到一个真实的例子)

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  <metadata>
    <id>web</id>
    <version>10.0.6</version>
    <authors>api</authors>
    <description>Package Description</description>
    <dependencies>
      <group targetFramework="net7.0">
        <dependency id="Swashbuckle.AspNetCore" version="6.2.3" exclude="Build,Analyzers" />
      </group>
    </dependencies>
    <frameworkReferences>
      <group targetFramework="net7.0">
        <frameworkReference name="Microsoft.AspNetCore.App" />
      </group>
    </frameworkReferences>
    <contentFiles>
      <files include="any/net7.0/appsettings.Development.json" buildAction="Content" />
      <files include="any/net7.0/appsettings.json" buildAction="Content" />
    </contentFiles>
  </metadata>
   <files>
     <file src="bin\Release\net7.0\api.dll" target="lib\net7.0" />
     <file src="bin\Release\net7.0\core.dll" target="lib\net7.0" />
     <file src="bin\Release\net7.0\infrastructure.dll" target="lib\net7.0" />
     <file src="bin\Release\net7.0\application.dll" target="lib\net7.0" />
  </files>
</package>

请注意,该版本在此文件中指定,将不再适用于.csproj或命令行。

将此命令运行到project/web文件夹中: do.net pack --output C:/MyNugetSource -c Release -p:NuspecFile=web.nuspec

这种方法不会弄乱代码,但依赖于操作配置文件并注意目录名称。 这会影响 CI 管道。

最后,我认为最好的方法是为解决方案中的每个项目创建 nuget 个包,在实践中对核心、基础设施和应用程序进行版本控制,并分别安装每一个,值得评估其可行性。

这个答案是基于这篇文章

对不起我的英语,我希望这会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM