Introduction
.NET 6 Implicit Using or Global Using? What makes more sense?
In .NET 6, we see there’s a lot of new features that make using .NET 6 easier. They may range from little things like being able to write an entire console app on a single line to ASP.NET minimal APIs which is far less code (without any controllers).
Two of these new features are Implicit Usings and Global Usings which both aim to reduce the number of using statements we need to add to new .cs files.
What are Implicit Using statements?
If you create a new ASP.NET API using the template and then open up the .csproj
file, you’ll find that Implicit Usings are enabled by default (line 6):
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
</Project>
What this basically does is provide some implicit usings to all files so you don’t have to keep adding them to each file you create. By default, .NET adds the below using statements (see here) which is quite handy but can cause some issues which we’ll talk about later:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
What are Global Using statements?
Global Using statements are using statements that are global (duh!). Okay, what this means is that they are using statements in a single file and they apply to all files in your .NET project. An example Global Usings file may look like this:
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading;
global using System.Threading.Tasks;
Now, you can add whatever you want here to make your life easier. The file name doesn’t have to be anything in particular so can be anything ending in .cs.
Implicit Using vs Global Using statements?
Now, here’s the fun part – what is better to use? Implicit or Global using statements?
Let’s assume you’re a good developer and are following SOLID principles. That first S stands for the Single Responsibility Principle and that basically states that a class should only have one reason to change. An example might be that it’s got business logic in it to handle new orders from customers. You then don’t want to be using HttpClient or similar to make calls out to external APIs. You’d want to have that code held in a client or something that you can abstract behind an interface and mock in your unit tests.
So, with this in mind, one thing that you can use to figure out what a class is doing is by looking at the constructor. A constructor with many many parameters isn’t a good sign and suggests that the class is doing many things. Another thing is the list of using statements. Now, here’s where things get interesting. If you look at the list of using statements included in the implicit using statements above, you’ll see that most of them are quite harmless – e.g. System
(i.e. you’re just using a DateTime
) or System.Linq
(where you’re just filtering a list of something) but some have a little more impact such as System.Net.Http
which suggests we may be using an HttpClient
to talk to an external API or System.IO
which may mean we’re writing out a file to disk. Both of these we’d want to know about.
So, what I tend to do for new projects is to disable Implicit Using statements and then just add a cut down version of the using statements into a GlobalUsings.cs file at the root of the project and I wouldn’t include System.IO
or System.Net.Http
as I’d want to know if those using statements are required by a class when I open up the class. My usual using statements are below:
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading;
global using System.Threading.Tasks;
Conclusion
In this post, we’ve taken a quick look at Implicit Usings and Global Usings and discussed the benefits of each. Most likely you’d want to do something similar in that you’d want to only put common and un-interesting global using statements into a file at the root of your project so you are more aware of what your class is referencing.