.NET Core 2.2 中的 Metapackage 和 SDK 有啥区别?

Posted

技术标签:

【中文标题】.NET Core 2.2 中的 Metapackage 和 SDK 有啥区别?【英文标题】:What is the difference between Metapackage and SDK in .NET Core 2.2?.NET Core 2.2 中的 Metapackage 和 SDK 有什么区别? 【发布时间】:2019-08-04 12:26:40 【问题描述】:

我试图在 .NET Core 术语中区分这两个概念。我将尝试用一个例子来说明我的困惑。

当我创建一个新的类库项目(例如:dotnet new classlib -o myclasslib)时,生成的.csproj 文件如下所示:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
</Project>

到目前为止一切顺利。现在,如果我尝试在这个项目中添加 WebApi 控制器类(例如,为了在创建为 dotnet new webapi -o mywebapi 的主 WebApi 应用程序中动态加载插件),我需要使用 ControllerBase 类和 [ApiController] 之类的东西和[HttpGet] 属性。为了简单起见,我只是从 ControllerBase 派生 MyController,如下所示:

using System;

namespace myclasslib

    public class MyController : Microsoft.AspNetCore.Mvc.ControllerBase
    
    

尝试使用 dotnet build 构建它我得到错误:

错误 CS0234:类型或命名空间名称“AspNetCore”不存在 在命名空间“Microsoft”中(您是否缺少程序集引用?)

这是意料之中的,因为我创建了 classlib 项目,但是如果将 .csproj 中的 SDK 更改为 Sdk="Microsoft.NET.Sdk.Web" 并将 TargetFramework 更改为 netcoreapp2.2(希望解决对 ControllerBase 类的引用),如下所示:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>
</Project>

我在构建项目时遇到了同样的错误。 SDK不应该包含我构建项目所需的一切吗?

如果我创建通常的 webapi 项目(例如 dotnet new webapi -o mywebapi),生成的 .csproj 看起来像这样:

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

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
  </ItemGroup>

</Project>

我注意到SDK和我设置的一样,但还添加了一个元包:&lt;PackageReference Include="Microsoft.AspNetCore.App" /&gt;

如果我们已经指定要使用 Microsoft.NET.Sdk.Web,为什么还需要显式添加元包?

另外一个问题:如果我们没有在 PackageReference 中指定一个元包版本(比如在这个生成的 webapi .csproj 中),那么使用什么版本的元包?

【问题讨论】:

【参考方案1】:

SDK 只是构建工具和 .NET Core 框架本身。 ASP.NET Core 是一组 NuGet 包。本质上是 .NET Core 框架!= ASP.NET Core 代码。元包的概念只是切线相关的。所谓的“ASP.NET Core”实际上是几十个单独的 NuGet 包。您可以单独引用每个,但正如您可以想象的那样,这既烦人又容易出错。元包本质上是一个 NuGet 包,它依赖于多个其他 NuGet 包。

因此,通过仅拉入元包,基本上所有元包的依赖项拉入。因此,您只需为Microsoft.AspNetCore.App 添加包引用即可到比赛。但是,这样做的缺点是您可能会获得实际上不需要的依赖项。对于像 Web 应用程序这样的东西来说,这不是什么大问题,因为可以修剪依赖关系,但类库不应该有过多的依赖关系。因此,您应该只从 Microsoft.AspNetCore 命名空间中引用您实际需要的单个 NuGet 包。

【讨论】:

以上是关于.NET Core 2.2 中的 Metapackage 和 SDK 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

.NET Core 2.2 中的 Metapackage 和 SDK 有啥区别?

ASP.NET Core 2.2 中的 Azure AD 身份验证

asp.Net core 2.2中的多种身份验证方法

ASP.NET Core 2.2 Razor 页面中的自定义路由

ASP.NET CORE 2.2 WEB APP中的会话过期问题

将 IConfigurationRoot 部分的更改保存到 .net Core 2.2 中的 *.json 文件