这个事情的起因是有两个大体相同的 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 为例,有以下几种:
- ASP.NET Core Runtime 6.0.10
- .NET Desktop Runtime 6.0.10
- .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.* 等类库,所以我们的项目在发布时就不用携带一堆重复的文件了。
借用群里大佬的一句话就是:
羊毛要么在羊身上,要么在羊圈里。