Ema*_*mad 6 c# asp.net-core .net-standard .net-standard-2.0
我正在使用ASP.NET Core 2.0编写MVC网站.
在ASP.NET Core项目中(让我们称之为Web),我在同一个解决方案中引用了.NET Standard 2项目(让我们称之为Service).该Service项目还引用了解决方案中的第三个.NET Standard 2库(让我们称之为Business).该Business项目声明了一个名为的类型Model.
问题是我可以Model在Web项目中使用(即编译器看到类型Model,我可以做var a = new Model();),就像Web项目已经引用一样Business,但它实际上只有一个引用Service.
如何隐藏Model的Web?这是ASP.NET Core 2中的新功能还是所有.NET Standard项目都是这样的?
编辑
如此处所述,这是由于传递项目引用,这是.NET Standard中的一个新"功能",但我该如何解决它?
Mar*_*ski 16
ProjectReference)可传递项目引用是.NET Core/.NET >= 5 中使用的 SDK 样式 csproj ( 1 , 2 ) 格式的新功能。您也可以将此 csproj 用于旧的 .NET Framework 项目(1、2、3),但使用一些例外。
在此 SDK 样式格式中,项目引用(由<ProjectReference>.csproj 文件中的条目表示)是可传递的。这与之前使用的旧的非 SDK .csproj 不同。
但是你有三个选项可以回到旧的非传递行为。
使用<DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences>.csproj 中的属性来引用您不希望编译器可见其传递依赖项的项目。
在您的情况下,您可以将其添加到Web项目中。(第一个引用其他项目的项目,Web -> Service -> Business)
您还可以通过在放置在包含源的根文件夹中的Directory.Build.props文件中为所有 .csprojs 全局设置此行为。
<Project>
<PropertyGroup>
<DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences>
</PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
使用此文件,您基本上拥有旧的项目参考行为。当您将使用旧 csproj 格式的旧 .NET Framework 解决方案迁移到新的 SDK 样式 .csprojs 时很有用。
在您引用的项目上,您可以设置 在引用该项目时哪些依赖项不应进一步流动。为此,您可以使用PrivateAssets="All"属性 on <ProjectReference>。例如,您可以像这样编辑Service .csproj:
<ItemGroup>
<ProjectReference Include="..\Business.csproj" PrivateAssets="All" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
这是一种更灵活和细粒度的方法。当项目被引用时,您可以控制特定的可传递项目引用应该是可见的。
使用ItemDefinitionGroup定义默认<PrivateAssets>all</PrivateAssets>为所有元数据ProjectReference秒。如果要将其全局应用于所有项目,也可以在Directory.Build.props文件中定义它。
<Project>
<PropertyGroup>
<DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences>
</PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
效果与设置<ProjectReference Include="..."> <PrivateAssets>All</PrivateAssets> </ProjectReference>(或 所有条目的PrivateAssets="All" 属性)相同ProjectReferences。
与使用 1. 方法 ( DisableTransitiveProjectReferences)的不同之处在于,如果您PrivateAssets在ProjectReferenceitem上明确定义元数据,则使用此值。您可以将使用ItemDefinitionGroup视为提供PrivateAssets元数据默认值的一种方式,它没有明确提供。
你应该用什么?这取决于你喜欢什么。如果您习惯了旧的 csproj 行为或想要将旧的解决方案迁移到 .NET Core,那么在Directory.Build.props 中使用 DisableTransitiveProjectReferences或是最简单的解决方案。ItemDefinitionGroup
PackageReference默认情况下,Nuget 引用 ( ) 也是可传递的。这不是严格回答您的问题,而是您也应该注意的事情。
如果您PackageReference为 nuget 包使用新格式(您可能会这样做,因为这是新的 SDK 样式的 csproj 文件中的默认格式),那么您还应该注意这些引用是可传递的。如果您的项目引用了另一个ProjectReference引用 nuget 包 (with PackageReference) 的项目(with ),那么您的项目也将引用此 nuget 包。
这里ProjectA将隐式引用Newtosoft.Json库。
不幸的是,没有用于包引用的DisableTransitivePackagesReferences。但是您可以像在第二个选项中那样使用PrivateAssets元数据,也ProjectReference可以ItemDefinitionGroup像在第三个选项中那样使用。
这就是为什么如果要禁用所有项目的项目和包引用的传递依赖项,那么Directory.build.props文件应如下所示:
<ItemGroup>
<ProjectReference Include="..\Business.csproj" PrivateAssets="All" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
(来源:我从这个博客中了解到了这项技术)
Roy*_*bat 11
目前,上述所有答案都不适用于 nuget 包依赖项。
对于以下库项目 (PrivateAssets="all"):
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>Roy</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" PrivateAssets="all" />
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
将生成以下 nuspec 文件:
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>MyLib</id>
<version>1.0.0</version>
<authors>Roy</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package Description</description>
<dependencies>
<group targetFramework=".NETStandard2.0" />
</dependencies>
</metadata>
</package>
Run Code Online (Sandbox Code Playgroud)
请注意“Newtonsoft.Json”甚至没有被指定为依赖项。这显然不起作用,因为 Visual Studio 甚至不会意识到该依赖关系,并且使用项目将无法在运行时解析“Newtonsoft.Json”。
正确答案是设置PrivateAssets="compile"。
这将产生以下 nuspec 文件:
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>MyLib</id>
<version>1.0.0</version>
<authors>Roy</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package Description</description>
<dependencies>
<group targetFramework=".NETStandard2.0">
<dependency id="Newtonsoft.Json" version="13.0.1" include="Runtime,Build,Native,ContentFiles,Analyzers,BuildTransitive" />
</group>
</dependencies>
</metadata>
</package>
Run Code Online (Sandbox Code Playgroud)
这将阻止使用项目在代码中访问 Newtonsoft.Json 命名空间,同时编译和复制所有必需的程序集以允许“封装”库工作。
Ema*_*mad 10
好吧,我的问题接近一个标记为重复的问题,但解决它需要不同的策略.
感谢"Federico Dipuma"的评论和这里给出的答案,我能够解决这个问题.
您应该编辑该Service.csproj文件并添加PrivateAssets="All"到ProjectReference您不希望流向顶部的键.
<ItemGroup>
<ProjectReference Include="..\Business.csproj" PrivateAssets="All" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1364 次 |
| 最近记录: |