这个事情的起因是有两个大体相同的 Worker Service 项目,但编译输出的文件数量却相差甚远:一个是 21 个文件,另一个是 40+ 。

经过对比,多出来的文件全部以 Microsoft.Extensions.* 开头,文件列表如下:

Microsoft.Extensions.Configuration.Abstractions.dll
Microsoft.Extensions.Configuration.Binder.dll
Microsoft.Extensions.Configuration.CommandLine.dll
Microsoft.Extensions.Configuration.dll
Microsoft.Extensions.Configuration.EnvironmentVariables.dll
Microsoft.Extensions.Configuration.FileExtensions.dll
Microsoft.Extensions.Configuration.Json.dll
Microsoft.Extensions.Configuration.UserSecrets.dll
Microsoft.Extensions.DependencyInjection.Abstractions.dll
Microsoft.Extensions.DependencyInjection.dll
Microsoft.Extensions.FileProviders.Abstractions.dll
Microsoft.Extensions.FileProviders.Physical.dll
Microsoft.Extensions.FileSystemGlobbing.dll
Microsoft.Extensions.Hosting.Abstractions.dll
Microsoft.Extensions.Hosting.dll
Microsoft.Extensions.Logging.Abstractions.dll
Microsoft.Extensions.Logging.Configuration.dll
Microsoft.Extensions.Logging.Console.dll
Microsoft.Extensions.Logging.Debug.dll
Microsoft.Extensions.Logging.dll
Microsoft.Extensions.Logging.EventLog.dll
Microsoft.Extensions.Logging.EventSource.dll
Microsoft.Extensions.Options.ConfigurationExtensions.dll
Microsoft.Extensions.Options.dll
Microsoft.Extensions.Primitives.dll

两个项目都运用到了 Hostring 技术,为什么有的项目会不输出 Microsoft.Extensions.Hosting.dll 呢?详细对比了项目依赖后,发现输出较少的项目多了两个和 AspNetCore 相关的东西:

经过逐个对比,发现 Zero.Worker 引用的一个 Nuget 包有些特殊,它的 SDK 是 Microsoft.NET.Sdk.Web ,也就是一个网站类库。

一个项目的 Sdk 类型由其 csproj 文件的第一行决定,大概是下面这样:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

这个项目的 Sdk 就是 Microsoft.NET.Sdk,是一个控制台应用程序,对应的框架是:Microsoft.NETCore.App。WEB 项目的 Sdk 对应的是 Microsoft.NET.Sdk.Web,框架还另外包含了 Microsoft.AspNetCore.App

通过查阅框架依赖,发现 Microsoft.AspNetCore.App 是默认包含上文中 Microsoft.Extensions.*所示依赖的。这可以通过 Visual Studio 查看,也可以在 NuGet 上看到:

至此,我们的疑问便有了一个理论上的解法:把 TestWorker 项目也加上那个特殊的引用包,看看输出结果会不会变少。经过尝试,这确实可以。

在 .NET 发布了 Core 版本之后,下载运行时的时候就有很多选择,以 6.0.10 为例,有以下几种:

  1. ASP.NET Core Runtime 6.0.10
  2. .NET Desktop Runtime 6.0.10
  3. .NET Runtime 6.0.10

如果我们只安装了 .NET Runtime 6.0.10 ,那么运行 WEB 程序是要报错的。但这并不妨碍我们运行 Worker Service 项目,只不过要把 Microsoft.Extensions.* 等一众 dll 带上即可。

如果我们的项目直接或间接依赖了 AspNetCore 项目,那么运行时就必须已经将 ASP.NET Core Runtime 准备好。又因为 ASP.NET Core Runtime 里面默认已经依赖了 Microsoft.Extensions.* 等类库,所以我们的项目在发布时就不用携带一堆重复的文件了。

借用群里大佬的一句话就是:

羊毛要么在羊身上,要么在羊圈里。

作者:Soar、毅 发布:2022-11-05 15:26:17 浏览:1,888)