gpt4 book ai didi

c# - 在 .NET Standard 2 中禁用传递项目引用

转载 作者:太空狗 更新时间:2023-10-29 22:29:48 29 4
gpt4 key购买 nike

我正在使用 ASP.NET Core 2.0 编写一个 MVC 网站。

在 ASP.NET Core 项目(我们称之为 Web)中,我在同一解决方案中引用了一个 .NET Standard 2 项目(我们称之为 Service)。 Service 项目还在解决方案中引用了第三个 .NET Standard 2 库(我们称之为 Business)。 Business 项目声明了一个名为 Model 的类型。

问题是我可以在 Web 项目中使用 Model(即编译器看到类型 Model 并且我可以做 var a = new Model();) 就好像 Web 项目引用了 Business,但实际上它只引用了 Service.

如何从 Web 中隐藏 Model?这是 ASP.NET Core 2 中的新功能还是所有 .NET Standard 项目都是这样?

编辑

按规定here ,这是由于传递性项目引用所致,这是 .NET Standard 中的一项新“功能”,但我该如何修复它?

最佳答案

传递项目引用(ProjectReference)

传递项目引用是 .NET Core/.NET >= 5 中使用的 SDK 样式 csproj(12)格​​式的新功能。您还可以将此 csproj 用于旧的 .NET Framework 项目(123 ) 但有一些 exceptions

在此 SDK 样式格式中,项目引用(由 .csproj 文件中的 <ProjectReference> 条目表示)是可传递的。这与之前使用的旧非 SDK .csproj 不同。

但是您有三种选择可以返回到旧的非传递行为。

  1. 在 .csproj 中使用 <DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences> 属性引用您不希望其传递依赖项被编译器可见的项目。

    在您的情况下,您可以将其添加到Web 项目。 (第一个引用其他项目的项目,Web -> Service -> Business)

    您还可以在您放入包含源代码的根文件夹中的 Directory.Build.props 文件中为所有 .csprojs 全局设置此行为。

     <Project>
    <PropertyGroup>
    <DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences>
    </PropertyGroup>
    </Project>

    有了这个文件,您基本上就有了旧的项目引用行为。当您将使用旧 csproj 格式的旧 .NET Framework 解决方案迁移到新的 SDK 样式的 .csprojs 时很有用。

  2. 在您引用的项目上,您可以设置在引用项目时哪些依赖项不应流动。为此,您在 PrivateAssets="All" 上使用 <ProjectReference> 属性。例如,您可以像这样编辑 Service.csproj:

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

    这是一种更加灵活和细粒度的方法。您可以控制特定的传递项目引用在引用项目时是否可见。

  3. 使用 ItemDefinitionGroup 为所有 <PrivateAssets>all</PrivateAssets> 定义默认的 ProjectReference 元数据。如果您想将它全局应用到所有项目,您也可以在 Directory.Build.props 文件中定义它。

    <ItemDefinitionGroup>
    <ProjectReference>
    <PrivateAssets>all</PrivateAssets>
    </ProjectReference>
    </ItemDefinitionGroup>

    效果与在所有 <ProjectReference Include="..."> <PrivateAssets>All</PrivateAssets> </ProjectReference> 条目上设置 PrivateAssets="All"(或 ProjectReferences attribute)相同。

    与使用 1. 方法 ( DisableTransitiveProjectReferences ) 的不同之处在于,如果您在 PrivateAssets 项目上明确定义 ProjectReference 元数据,则使用此值。您可以考虑使用 ItemDefinitionGroup 作为提供默认值 PrivateAssets 元数据的方法,它没有明确提供。

你应该使用什么?这取决于你喜欢什么。如果您习惯了旧的 csproj 行为或想要将旧的解决方案迁移到 .NET Core,那么在您的 Directory.Build.props 中使用 DisableTransitiveProjectReferencesItemDefinitionGroup 是最简单的解决方案。


Nuget 引用 ( PackageReference ) 默认也是可传递的。

这并不是严格回答您的问题,但您也应该注意这一点。

如果您正在为 nuget 包使用新的 PackageReference 格式(您可能会这样做,因为这是新的 SDK 样式的 csproj 文件中的默认格式),那么您还应该知道这些引用是可传递的。如果您的项目引用另一个引用 nuget 包(ProjectReference)的项目(PackageReference),那么您的项目也将引用此 nuget 包。

Diagram showing ProjectA referencing ProjectB which references Newtonsoft.Jon package

此处 ProjectA 将隐式引用 Newtosoft.Json 库。

不幸的是,包引用有 no DisableTransitivePackagesReferences。但是您可以像在第二个选项中对 ProjectReference 那样使用 PrivateAssets 元数据,或者像在第三个选项中那样使用 ItemDefinitionGroup

这就是为什么如果您想禁用所有项目的项目和包引用的传递依赖性,那么您的Directory.build.props 文件应该如下所示:

<Project>
<ItemDefinitionGroup>
<ProjectReference>
<PrivateAssets>all</PrivateAssets>
</ProjectReference>
<PackageReference>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemDefinitionGroup>
</Project>

(来源:我从这个 blog 了解到这个技术)

<Project>
<ItemDefinitionGroup>
<DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences>
<PackageReference>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemDefinitionGroup>
</Project>

关于c# - 在 .NET Standard 2 中禁用传递项目引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46709000/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com