Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDK support for implicit namespaces in C# projects #25066

Closed
4 of 25 tasks
JunTaoLuo opened this issue Jul 9, 2021 · 4 comments · Fixed by #25250 or #25410
Closed
4 of 25 tasks

SDK support for implicit namespaces in C# projects #25066

JunTaoLuo opened this issue Jul 9, 2021 · 4 comments · Fixed by #25250 or #25410
Assignees
Labels
breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 6 Issues and PRs for the .NET 6 release doc-idea Indicates issues that are suggestions for new topics [org][type][category] Pri1 High priority, do before Pri2 and Pri3

Comments

@JunTaoLuo
Copy link

JunTaoLuo commented Jul 9, 2021

SDK support for implicit namespaces in C# projects

We are introducing implicit namespace support for C# projects in the .NET SDK. The goal is to reduce the amount of boilerplate in .NET C# project templates by removing the need for using statements at the top of most files with the global using feature introduced in C# 10.

Implicit namespace will be enabled by default for C# projects targeting the net6.0 TFM or higher and using Microsoft.NET.Sdk, Microsoft.NET.Sdk.Web or Microsoft.NET.Sdk.Worker SDK. A generated file containing the default namespaces will be included in the set of files passed to the compiler. Projects using a C# version less than 10 need to explicitly disable this feature.

Modifying the list of implicit namespaces

There are three ways to control the namespaces that are included in the project:

  1. Disable the feature completely by setting <DisableImplicitNamespaceImports> to true in the project file.
  2. Disable a set of implicit namespaces added by a SDK, see the list of SDK specific namespace imports below for the setting name.
  3. Add or remove individual namespaces in the project file by modifying the <Import> item group in the project file. For example
<ItemGroup>
  <Import Remove="System.Net.Http" />
  <Import Include="System.IO.Pipes" />
</ItemGroup>

These are the implicit namespaces added to projects using the following SDKs:

Microsoft.NET.Sdk

The following list of namespaces will be added:

System
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading
System.Threading.Tasks

This set of implicit namespace imports can be disabled by setting <DisableImplicitNamespaceImports_DotNet> to true in the project file.

Microsoft.NET.Sdk.Web

The following list of namespaces will be added in addition to the ones added by the Microsoft.NET.Sdk:

System.Net.Http.Json
Microsoft.AspNetCore.Builder
Microsoft.AspNetCore.Hosting
Microsoft.AspNetCore.Http
Microsoft.AspNetCore.Routing
Microsoft.Extensions.Configuration
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Hosting
Microsoft.Extensions.Logging

This set of implicit namespace imports can be disabled by setting <DisableImplicitNamespaceImports_Web> to true in the project file.

Microsoft.NET.Sdk.Worker

The following list of namespaces will be added in addition to the ones added by the Microsoft.NET.Sdk:

Microsoft.Extensions.Configuration
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Hosting
Microsoft.Extensions.Logging

This set of implicit namespace imports can be disabled by setting <DisableImplicitNamespaceImports_Worker> to true in the project file.

Version introduced

6.0-preview7

Old behavior

No implicit namespaces are added for applicable C# projects.

New behavior

Implicit namespaces are added via global usings in a generated file in the obj directory. See how to control the list of included implicit namespaces above.

Category

  • Binary compatibility (code must be recompiled to use the newer API version)
  • Source compatibility (successfully recompiling against the newer API version requires source changes)

There is a potential need to resolve type conflicts due to the introduction of implicit namespaces.

Reason for change

These changes in the SDK are made to reduce the amount of boilerplate using statements that appear at the top of most C# projects.

Recommended action

This feature will be enabled by default and for most users, no action will need to be taken. However, the introduction of this mechanism can cause type name conflicts with the namespaces listed above. In those cases, action need to be take to modify the list of implicit namespaces

Feature area

  • ASP.NET Core
  • C#
  • Code analysis
  • Core .NET libraries
  • Cryptography
  • Data
  • Debugger
  • Deployment
  • Globalization
  • Interop
  • JIT
  • LINQ
  • Managed Extensibility Framework (MEF)
  • MSBuild
  • Networking
  • Printing
  • SDK
  • Security
  • Serialization
  • Visual Basic
  • Windows Forms
  • Windows Presentation Foundation (WPF)
  • XML, XSLT

Affected APIs

Finally, please remember to email a link to this breaking change issue to .NET Breaking Change Notifications.


Issue metadata

  • Issue type: breaking-change
@JunTaoLuo JunTaoLuo added the breaking-change Indicates a .NET Core breaking change label Jul 9, 2021
@PRMerger9 PRMerger9 added the Pri3 label Jul 9, 2021
@dotnet-bot dotnet-bot added ⌚ Not Triaged Not triaged doc-idea Indicates issues that are suggestions for new topics [org][type][category] labels Jul 9, 2021
@gewarren gewarren self-assigned this Jul 14, 2021
@gewarren gewarren added Pri1 High priority, do before Pri2 and Pri3 and removed ⌚ Not Triaged Not triaged Pri3 labels Jul 14, 2021
@danmoseley
Copy link
Member

It might be helpful to show one potential error you might get, specifically if you're authoring an MSBuild task, and thus deriving from the Task abstract class, you will see errors like this because it conflicts with the Task class in System.Threading.Tasks, which is now being implicitly included:

...: error CS0104: 'Task' is an ambiguous reference between 'Microsoft.Build.Utilities.Task' and 'System.Threading.Tasks.Task' 
.... error CS0115: 'SomeTask.Execute()': no suitable method found to override 

If you get the above, you will need to disable this feature for the project.

@danmoseley danmoseley reopened this Jul 30, 2021
@danmoseley
Copy link
Member

cc @gewarren

@xPaw
Copy link
Contributor

xPaw commented Aug 12, 2021

So was there no discussion around this change? This change feels questionable to me, especially with the default lists. How did you arrive at these defaults?

@TheMarkie
Copy link

Arbitrary, sloppy implicit namespace polution can really use a warning that goes something like:
This class conflicts with another class from an implicit namespace, you can turn it off here since you don't need it.

Boilerplate that the project does for you is still boilerplate by the way, in case your college book didn't teach you that. Namespaces and using instructions are important enough that they should remain explicit and "boilerplate" for the sake of good etiquette. This change can have negative ramification for new developers in the same way that implicit using namespace std; might.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Indicates a .NET Core breaking change 🏁 Release: .NET 6 Issues and PRs for the .NET 6 release doc-idea Indicates issues that are suggestions for new topics [org][type][category] Pri1 High priority, do before Pri2 and Pri3
Projects
Development

Successfully merging a pull request may close this issue.

7 participants