[.NET 6][C#] using "using directive"
Tags: csharp
Published: 2021-12-13 17:32:49

## Intro

From .NET 6(C# 10), I can use "global using" and "ImplicitUsing".
And I have never used "using static".

This time, I will try using "using directive".

### Environments
* .NET 6.0.100

## Try
### Basic usage

When I refer classes what are in other namespaces from a class,
I can omit writing full namespaces by using directive.

#### IApplicationUserService.cs
```csharp
...
namespace ApprovementWorkflowSample.Applications
{
    public interface IApplicationUserService
    {
...
    }
}
```

#### UserController.cs
```cs
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

// To refer "ApprovementWorkflowSample.Applications.IApplicationUserService.cs" 
using ApprovementWorkflowSample.Applications;

namespace ApprovementWorkflowSample.Controllers
{
    public class UserController: Controller
    {
        private readonly ILogger<UserController> logger;
        private readonly IApplicationUserService users;
        public UserController(ILogger<UserController> logger,
                IApplicationUserService users)
        {
            this.logger = logger;
            this.users = users;
        }
...
    }
}
```

### alias

If there are two or more classes (interfaces, etc.) in different namespaces, I can't omit the namespaces.

#### IApplicationUserService.cs
```csharp
...
namespace ApprovementWorkflowSample.Users
{
    public interface IApplicationUserService
    {
...
    }
}
```

#### UserController.cs
```cs
...
using ApprovementWorkflowSample.Applications;
using ApprovementWorkflowSample.Users;

namespace ApprovementWorkflowSample.Controllers
{
    public class UserController: Controller
    {
        private readonly ILogger<UserController> logger;

        // Compiling error
        private readonly IApplicationUserService users;
        public UserController(ILogger<UserController> logger,
                // Compiling error
                IApplicationUserService users)
        {
            this.logger = logger;
            this.users = users;
        }
...
    }
}
```

To avoid this error, I can write full namespaces or use aliases.

#### UserController.cs
```cs
...
using ApUsers = ApprovementWorkflowSample.Applications;
using ApprovementWorkflowSample.Users;

namespace ApprovementWorkflowSample.Controllers
{
    public class UserController: Controller
    {
        private readonly ILogger<UserController> logger;
        // OK
        private readonly ApprovementWorkflowSample.Applications.IApplicationUserService users;
        public UserController(ILogger<UserController> logger,
                // OK
                ApUsers.IApplicationUserService users)
        {
            this.logger = logger;
            this.users = users;
        }
```

If the alias is as same as another class(or interface, etc.) name, I will get compiling errors.

#### ApUsers.cs
```cs
namespace ApprovementWorkflowSample.Controllers;
public class ApUsers
{   
}
```

#### UserController.cs
```cs
...
using ApUsers = ApprovementWorkflowSample.Applications;
using ApprovementWorkflowSample.Users;

namespace ApprovementWorkflowSample.Controllers
{
    public class UserController: Controller
    {
        private readonly ILogger<UserController> logger;
        private readonly ApprovementWorkflowSample.Applications.IApplicationUserService users;
        public UserController(ILogger<UserController> logger,
                // Compiling error
                ApUsers.IApplicationUserService users)
        {
            this.logger = logger;
            this.users = users;
        }
```

To avoid this, I can use "::".

#### UserController.cs
```cs
...
using ApUsers = ApprovementWorkflowSample.Applications;
using ApprovementWorkflowSample.Users;

namespace ApprovementWorkflowSample.Controllers
{
    public class UserController: Controller
    {
        private readonly ILogger<UserController> logger;
        private readonly ApprovementWorkflowSample.Applications.IApplicationUserService users;
        public UserController(ILogger<UserController> logger,
                // OK
                ApUsers::IApplicationUserService users)
        {
            this.logger = logger;
            this.users = users;
        }
```

### using static
I can use static methods or static members.

#### UserController.cs
```cs
...
using static System.Console;

namespace ApprovementWorkflowSample.Controllers
{
    public class UserController: Controller
    {
        private readonly ILogger<UserController> logger;
        private readonly ApprovementWorkflowSample.Applications.IApplicationUserService users;
        public UserController(ILogger<UserController> logger,
                ApUsers::IApplicationUserService users)
        {
...
            WriteLine("Hello");
        }
```

### global using

I can use "global using" and omit write full namespaces.

#### IApplicationUserService.cs
```csharp
// I must write "global using" on the top of the file or I will get a compiling error.
global using AppUserService = ApprovementWorkflowSample.Applications.IApplicationUserService;
...
namespace ApprovementWorkflowSample.Users;
public interface IApplicationUserService
{
...
}
```

#### UserController.cs
```cs
using ApUsers = ApprovementWorkflowSample.Applications;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace ApprovementWorkflowSample.Controllers
{
    public class UserController: Controller
    {
        private readonly ILogger<UserController> logger;

        // I don't need writing using directive.
        private readonly AppUserService users;

        public UserController(ILogger<UserController> logger,
                // Of cource, the type of "AppUserService" is as same as "IApplicationUserService".
                ApUsers::IApplicationUserService users)
        {
            this.logger = logger;
            this.users = users;
        }
...
    }
}
```

#### using same name?

If I add a class what is named "AppUserService", I will get a compiling error.

#### AppUserService.cs
```cs
namespace ApprovementWorkflowSample.Controllers;
public class AppUserService
{   
}
```
#### UserController.cs
```cs
using ApUsers = ApprovementWorkflowSample.Applications;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace ApprovementWorkflowSample.Controllers
{
    public class UserController: Controller
    {
        private readonly ILogger<UserController> logger;
        // this treated as "ApprovementWorkflowSample.Controllers.AppUserService"
        private readonly AppUserService users;

        public UserController(ILogger<UserController> logger,
                ApUsers::IApplicationUserService users)
        {
            this.logger = logger;
            // Compiling error.
            this.users = users;
        }
...
    }
}
```

### ImplicitUsings
I can omit "using System;", "using Microsoft.Extensions.Logging;", etc. by "ImplicitUsings".

#### ApprovementWorkflowSample.csproj
```xml
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
...
  </ItemGroup>
</Project>
```

* [using directive - Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive)
* [名前空間 -  C# によるプログラミング入門 - ++C++; // 未確認飛行C](https://ufcpp.net/study/csharp/sp_namespace.html)
* [Implicit Usings in .NET 6 - Scott Hanselman's Blog](https://www.hanselman.com/blog/implicit-usings-in-net-6#:~:text=%22.NET%206%20introduces%20implicit%20namespace%20support%20for%20C%23,Visual%20Basic%20has%20had%20this%20very%20feature%20forever%3F)
* [Announcing .NET 6 — The Fastest .NET Yet - .NET Blog](https://devblogs.microsoft.com/dotnet/announcing-net-6/)
* [【C# 10.0】 ImplicitUsings (自動 global using) - ++C++; // 未確認飛行C](https://ufcpp.net/blog/2021/11/implicitusings/)