Skip to content

Commit ec7f311

Browse files
committed
Avoid package dependencies on libraries in the shared framework (dotnet#106172)
* Avoid package dependencies on libraries in the shared framework We can avoid these dependencies since we can count on the library being part of the shared framework. Fewer dependencies means less packages downloaded, less for customers to service, less copied into the output directory when serviced. * Add warning code. * Address feedback
1 parent 5ce9f84 commit ec7f311

File tree

15 files changed

+57
-18
lines changed

15 files changed

+57
-18
lines changed

docs/coding-guidelines/libraries-packaging.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ Source generators and analyzers can be included in the shared framework by addin
1818

1919
Removing a library from the shared framework is a breaking change and should be avoided.
2020

21+
### References to libraries in the shared framework that produce packages
22+
23+
It's beneficial to avoid project references to libraries that are in the shared framework because it makes the package graph smaller which reduces the number of packages that require servicing and the number of libraries that end up being copied into the application directory.
24+
25+
If a dependency is part of the shared framework a project/package reference is never required on the latest version (`NetCoreAppCurrent`). A reference is required for previous .NET versions even if the dependency is part of the shared framework if the project you are building targets .NETStandard and references the project there. You may completely avoid a package dependency on .NETStandard and .NET if it's not needed for .NETStandard (for example - if it is an implementation only dependency and you're building a PNSE assembly for .NETStandard).
26+
27+
Warning NETPKG0001 is emitted when you have an unnecessary reference to a library that is part of the shared framework. To avoid this warning, make sure your ProjectReference is conditioned so that it doesn't apply on `NetCoreAppCurrent`.
28+
2129
## Transport package
2230

2331
Transport packages are non-shipping packages that dotnet/runtime produces in order to share binaries with other repositories.

eng/packaging.targets

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,21 @@
196196
</ItemGroup>
197197
</Target>
198198

199+
<Target Name="WarnOnProjectReferenceToFrameworkAssemblies"
200+
BeforeTargets="IncludeTransitiveProjectReferences"
201+
Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)' and
202+
'@(ProjectReference)' != ''">
203+
<!-- Find project references that overlap with NetCoreApp, are direct (NuGetPackageId is not set), actually referenced (ReferenceOutputAssembly), and not hidden with PrivateAssets
204+
ProjectReferences can opt out of this checking by setting AllowFrameworkPackageReference, though they should not. -->
205+
<Warning Text="Project reference '%(ProjectReference.Identity)' is a reference to a framework assembly and is not required in $(NetCoreAppCurrent) (NetCoreAppCurrent)."
206+
Code="NETPKG0001"
207+
Condition="$(NetCoreAppLibrary.Contains('%(ProjectReference.Filename);')) and
208+
'%(ProjectReference.ReferenceOutputAssembly)' != 'false' and
209+
'%(ProjectReference.NuGetPackageId)' == '' and
210+
'%(ProjectReference.PrivateAssets)' != 'all' and
211+
'%(ProjectReference.AllowFrameworkPackageReference)' != 'true'" />
212+
</Target>
213+
199214
<Target Name="GenerateMultiTargetRoslynComponentTargetsFile"
200215
Inputs="$(MSBuildProjectFullPath);$(_MultiTargetRoslynComponentTargetsTemplate)"
201216
Outputs="$(MultiTargetRoslynComponentTargetsFileIntermediatePath)">

src/libraries/Microsoft.Extensions.Configuration.Json/src/Microsoft.Extensions.Configuration.Json.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Configuration.Abstractions\src\Microsoft.Extensions.Configuration.Abstractions.csproj" />
1414
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Configuration.FileExtensions\src\Microsoft.Extensions.Configuration.FileExtensions.csproj" />
1515
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.FileProviders.Abstractions\src\Microsoft.Extensions.FileProviders.Abstractions.csproj" />
16-
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Json\src\System.Text.Json.csproj" />
1716
<Compile Include="$(CommonPath)System\ThrowHelper.cs"
1817
Link="Common\System\ThrowHelper.cs" />
1918
</ItemGroup>
2019

20+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
21+
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Json\src\System.Text.Json.csproj" />
22+
</ItemGroup>
23+
2124
</Project>

src/libraries/Microsoft.Extensions.DependencyModel/src/Microsoft.Extensions.DependencyModel.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,18 @@ By default, the dependency manifest contains information about the application's
2222
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
2323
<Compile Remove="**\*.netstandard.cs" />
2424
</ItemGroup>
25-
25+
2626
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
2727
<Compile Remove="**\*.netcoreapp.cs" />
2828
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\RequiresAssemblyFilesAttribute.cs" />
2929
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\UnconditionalSuppressMessageAttribute.cs" />
3030
</ItemGroup>
3131

3232
<ItemGroup>
33-
<InternalsVisibleTo Include="Microsoft.Extensions.DependencyModel.Tests" />
33+
<InternalsVisibleTo Include="Microsoft.Extensions.DependencyModel.Tests" />
3434
</ItemGroup>
3535

36-
<ItemGroup>
36+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
3737
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Encodings.Web\src\System.Text.Encodings.Web.csproj" />
3838
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Json\src\System.Text.Json.csproj" />
3939
</ItemGroup>
@@ -46,5 +46,5 @@ By default, the dependency manifest contains information about the application's
4646
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
4747
<Reference Include="System.Runtime" />
4848
</ItemGroup>
49-
49+
5050
</Project>

src/libraries/Microsoft.Extensions.Diagnostics.Abstractions/src/Microsoft.Extensions.Diagnostics.Abstractions.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ Microsoft.Extensions.Diagnostics.Metrics.MetricsOptions</PackageDescription>
3131
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\DynamicallyAccessedMemberTypes.cs" />
3232
</ItemGroup>
3333

34-
<ItemGroup>
34+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
3535
<ProjectReference Include="$(LibrariesProjectRoot)System.Diagnostics.DiagnosticSource\src\System.Diagnostics.DiagnosticSource.csproj" />
36+
</ItemGroup>
37+
38+
<ItemGroup>
3639
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.DependencyInjection.Abstractions\src\Microsoft.Extensions.DependencyInjection.Abstractions.csproj" />
3740
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Options\src\Microsoft.Extensions.Options.csproj" />
3841
</ItemGroup>

src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ Microsoft.Extensions.Logging.Abstractions.NullLogger</PackageDescription>
4040
<PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
4141
</ItemGroup>
4242

43+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
44+
<ProjectReference Include="$(LibrariesProjectRoot)System.Diagnostics.DiagnosticSource\src\System.Diagnostics.DiagnosticSource.csproj" />
45+
</ItemGroup>
46+
4347
<ItemGroup>
4448
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.DependencyInjection.Abstractions\src\Microsoft.Extensions.DependencyInjection.Abstractions.csproj" />
4549

src/libraries/Microsoft.Extensions.Logging.Console/src/Microsoft.Extensions.Logging.Console.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Logging.Abstractions\src\Microsoft.Extensions.Logging.Abstractions.csproj" />
5050
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Logging.Configuration\src\Microsoft.Extensions.Logging.Configuration.csproj" />
5151
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Options\src\Microsoft.Extensions.Options.csproj" />
52+
</ItemGroup>
53+
54+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
5255
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Json\src\System.Text.Json.csproj" />
5356
</ItemGroup>
5457

src/libraries/Microsoft.Extensions.Logging.EventSource/src/Microsoft.Extensions.Logging.EventSource.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Logging.Abstractions\src\Microsoft.Extensions.Logging.Abstractions.csproj" />
3030
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Options\src\Microsoft.Extensions.Options.csproj" />
3131
<ProjectReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Primitives\src\Microsoft.Extensions.Primitives.csproj" />
32-
<!-- Application tfms (.NETCoreApp, .NETFramework) need to use the same or higher version of .NETStandard's dependencies. -->
32+
</ItemGroup>
33+
34+
<!-- Application tfms (.NETCoreApp, .NETFramework) need to use the same or higher version of .NETStandard's dependencies. -->
35+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
3336
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Json\src\System.Text.Json.csproj" />
3437
</ItemGroup>
3538

src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,4 @@ System.Data.Odbc.OdbcTransaction</PackageDescription>
161161
<None Include="DatabaseSetupInstructions.md" />
162162
</ItemGroup>
163163

164-
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
165-
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Encoding.CodePages\src\System.Text.Encoding.CodePages.csproj" />
166-
</ItemGroup>
167164
</Project>

src/libraries/System.Memory.Data/src/System.Memory.Data.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ System.BinaryData</PackageDescription>
2323
<ItemGroup Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">
2424
<Compile Include="$(CommonPath)System\Threading\Tasks\TaskToAsyncResult.cs" Link="Common\System\Threading\Tasks\TaskToAsyncResult.cs" />
2525
</ItemGroup>
26-
27-
<ItemGroup>
26+
27+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
2828
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Json\src\System.Text.Json.csproj" />
2929
</ItemGroup>
3030

src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,15 @@ System.Net.Http.Json.JsonContent</PackageDescription>
5252
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\StringSyntaxAttribute.cs" />
5353
</ItemGroup>
5454

55-
<ItemGroup>
55+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
5656
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Json\src\System.Text.Json.csproj" />
5757
</ItemGroup>
5858

5959
<ItemGroup Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)'">
6060
<Reference Include="System.Net.Http" />
6161
<Reference Include="System.Net.Primitives" />
6262
<Reference Include="System.Runtime" />
63+
<Reference Include="System.Text.Json" />
6364
</ItemGroup>
6465

6566
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">

src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ The System.Reflection.Metadata library is built-in as part of the shared framewo
251251
<Compile Include="$(CommonPath)System\Obsoletions.cs" Link="Common\System\Obsoletions.cs" />
252252
</ItemGroup>
253253

254-
<ItemGroup>
254+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
255255
<ProjectReference Include="$(LibrariesProjectRoot)System.Collections.Immutable\src\System.Collections.Immutable.csproj" />
256256
</ItemGroup>
257257

@@ -261,6 +261,7 @@ The System.Reflection.Metadata library is built-in as part of the shared framewo
261261

262262
<ItemGroup Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)'">
263263
<Reference Include="System.Collections" />
264+
<Reference Include="System.Collections.Immutable" />
264265
<Reference Include="System.IO.Compression" />
265266
<Reference Include="System.IO.MemoryMappedFiles" />
266267
<Reference Include="System.Memory" />

src/libraries/System.Reflection.MetadataLoadContext/src/System.Reflection.MetadataLoadContext.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@
155155
<Compile Include="$(CoreLibSharedDir)System\Diagnostics\CodeAnalysis\RequiresUnreferencedCodeAttribute.cs" />
156156
</ItemGroup>
157157

158-
<ItemGroup>
159-
<!-- Application tfms (.NETCoreApp, .NETFramework) need to use the same or higher version of .NETStandard's dependencies. -->
158+
<!-- Application tfms (.NETCoreApp, .NETFramework) need to use the same or higher version of .NETStandard's dependencies. -->
159+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
160160
<ProjectReference Include="$(LibrariesProjectRoot)System.Collections.Immutable\src\System.Collections.Immutable.csproj" />
161161
<ProjectReference Include="$(LibrariesProjectRoot)System.Reflection.Metadata\src\System.Reflection.Metadata.csproj" />
162162
</ItemGroup>

src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ System.Security.Cryptography.Pkcs.EnvelopedCms</PackageDescription>
650650
<None Include="@(AsnXml)" />
651651
</ItemGroup>
652652

653-
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
653+
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' and '$(TargetFramework)' != '$(NetCoreAppCurrent)'">
654654
<ProjectReference Include="$(LibrariesProjectRoot)System.Formats.Asn1\src\System.Formats.Asn1.csproj" />
655655
</ItemGroup>
656656

src/libraries/System.Text.Json/src/System.Text.Json.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ The System.Text.Json library is built-in as part of the shared framework in .NET
381381
</ItemGroup>
382382

383383
<!-- Application tfms (.NETCoreApp, .NETFramework) need to use the same or higher version of .NETStandard's dependencies. -->
384-
<ItemGroup>
384+
<ItemGroup Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)'">
385385
<ProjectReference Include="$(LibrariesProjectRoot)System.Text.Encodings.Web\src\System.Text.Encodings.Web.csproj" />
386386
</ItemGroup>
387387

@@ -398,6 +398,7 @@ The System.Text.Json library is built-in as part of the shared framework in .NET
398398
<Reference Include="System.Runtime.Intrinsics" />
399399
<Reference Include="System.Runtime.Loader" />
400400
<Reference Include="System.Text.Encoding.Extensions" />
401+
<Reference Include="System.Text.Encodings.Web" />
401402
<Reference Include="System.Threading" />
402403
</ItemGroup>
403404

0 commit comments

Comments
 (0)