この記事では、.NET CLI を使用して.NET用のライブラリを記述する方法について説明します。 CLI は、サポートされる任意の OS で動作する効率的で低レベルのエクスペリエンスを提供します。 Visual Studioを使用してライブラリをビルドすることもできます。それが好みのエクスペリエンスである場合は、Visual Studio ガイド<参照>。
前提条件
コンピューターに .NET SDK がインストールされている必要があります。
.NET Framework のバージョンを扱うこのドキュメントのセクションでは、Windows コンピューターに .NET Framework がインストールされている必要があります。
また、以前の .NET Framework ターゲットをサポートする場合は、.NET Framework ダウンロード ページからターゲット パックまたは開発者パックをインストールする必要があります。 次の表を参照してください。
| .NET Framework のバージョン | ダウンロードするもの |
|---|---|
| 4.6.1 | .NET Framework 4.6.1 ターゲティング パック |
| 4.6 | .NET Framework 4.6 ターゲティング パック |
| 4.5.2 | .NET Framework 4.5.2 開発者パック |
| 4.5.1 | .NET Framework 4.5.1 Developer Pack |
| 4.5 | Windows 8用Windowsソフトウェア開発キット |
| 4.0 | Windows SDK for Windows 7 および .NET Framework 4 |
| 2.0、3.0、および 3.5 | .NET Framework 3.5 SP1 ランタイム (または Windows 8 以降のバージョン) |
.NET 5 以上または .NET Standard をターゲットにする方法
プロジェクト ファイル ( .csproj または .fsproj) に追加することでプロジェクトのターゲット フレームワークを制御します。 .NET 5+ または .NET Standard をターゲットに選択する方法については、「.NET 5+ と .NET Standard」を参照してください。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
.NET Framework バージョン 4.0 以下をターゲットにする場合、または .NET Framework で使用できる API を使用したいが、.NET Standard では使用できない場合 (例: System.Drawing)、次のセクションを読み、マルチターゲットする方法について説明します。
.NET Framework をターゲットにする方法
注意
次の手順では、.NET Framework がコンピューターにインストールされていることを前提としています。 依存関係のインストールについては、「前提条件」を参照してください。
ここで使用する .NET Framework バージョンの一部はサポートされなくなったことに注意してください。 サポートされていないバージョンについては、.NET Framework サポート ライフサイクル ポリシーに関する FAQ を参照してください。
開発者とプロジェクトの最大数に達する場合は、ベースライン ターゲットとして .NET Framework 4.0 を使用します。 .NET Framework をターゲットにするには、まず、サポートする .NET Framework バージョンに対応する適切なターゲット フレームワーク モニカー (TFM) を使用します。
| .NET Framework のバージョン | TFM |
|---|---|
| .NET Framework 2.0 | net20 |
| .NET Framework 3.0 | net30 |
| .NET Framework 3.5 | net35 |
| .NET Framework 4.0 | net40 |
| .NET Framework 4.5 | net45 |
| .NET Framework 4.5.1 | net451 |
| .NET Framework 4.5.2 | net452 |
| .NET Framework 4.6 | net46 |
| .NET Framework 4.6.1 | net461 |
| .NET Framework 4.6.2 | net462 |
| .NET Framework 4.7 | net47 |
| .NET Framework 4.8 | net48 |
この TFM をプロジェクト ファイルの セクションに挿入します。 たとえば、.NET Framework 4.0 を対象とするライブラリを作成する方法を次に示します。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net40</TargetFramework>
</PropertyGroup>
</Project>
以上で作業は終了です。 これは .NET Framework 4 用にのみコンパイルされましたが、新しいバージョンの .NET Framework でライブラリを使用できます。
マルチターゲットを設定する方法
注意
次の手順では、.NET Framework がコンピューターにインストールされていることを前提としています。 インストールする必要がある依存関係と、そのダウンロードできる場所については、「前提条件」セクションを参照してください。
プロジェクトで .NET Framework と .NET の両方がサポートされている場合は、古いバージョンの .NET Framework をターゲットにする必要がある場合があります。 このシナリオで、新しい API と新しいターゲット向けの言語構成を使用する場合、コードで ディレクティブを使用します。 また、必要に応じて、ターゲットにする各プラットフォームに応じて異なるパッケージと依存関係追加して、それぞれに異なる必要な API を含めます。
たとえば、HTTP 上でネットワークキング操作を行うライブラリがあるとします。 .NET Standard および .NET Framework バージョン 4.5 以降では、HttpClient 名前空間の System.Net.Http クラスを使用できます。 ただし、.NET Framework の以前のバージョンには HttpClient クラスがないため、代わりに WebClient 名前空間の System.Net クラスを使用できます。
プロジェクト ファイルは次のようになります。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net40;net45</TargetFrameworks>
</PropertyGroup>
<!-- Need to conditionally bring in references for the .NET Framework 4.0 target -->
<ItemGroup Condition="'$(TargetFramework)' == 'net40'">
<Reference Include="System.Net" />
</ItemGroup>
<!-- Need to conditionally bring in references for the .NET Framework 4.5 target -->
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<Reference Include="System.Net.Http" />
<Reference Include="System.Threading.Tasks" />
</ItemGroup>
</Project>
主な変更点が 3 つあります。
- ノードは で置き換えられ、3 つの TFM が内部に表現されています。
-
<ItemGroup>ターゲットのnet40ノードは、1 つの .NET Framework 参照を取り込んでいます。 -
<ItemGroup>ターゲットには、2 つの .NET Framework 参照を取り込むnet45ノードがあります。
プリプロセッサ シンボル
ビルド システムは ディレクティブで使用される次のプリプロセッサ シンボルを認識します。
| ターゲット フレームワーク | 記号 | 追加のシンボル (.NET 5 つ以上の SDK で利用可能) |
利用可能なプラットフォームシンボル (OS 固有のため) OS固有のTFMを指定する際に |
|---|---|---|---|
| .NET Framework | 、 、 、 、 、 、 、 、 、 、 、 、 、 、 | 、 、 、 、 、 、 、 、 、 、 、 、 | |
| .NET Standard | 、、、、、、、、、 | 、 、 、 、 、 、 、 、 | |
| .NET 5+ (および .NET Core) | 、 、 、 、 、 、 、 、 、 、 、 、 、 、 | 、 、 、 、 、 、 、 、 、 、 、 、 | 、 、 、 、 、 、 、 (例: )、 (例: ) |
注意
- バージョンレスのシンボルは、ターゲットとするバージョンに関係なく定義されます。
- バージョン固有のシンボルは、対象とするバージョンに対してのみ定義されます。
- シンボルは、ターゲットとするバージョンとそれ以前のすべてのバージョンに対して定義されます。 たとえば、.NET Framework 2.0 を対象とする場合は、
NET20、NET20_OR_GREATER、NET11_OR_GREATER、およびNET10_OR_GREATERという記号が定義されます。 -
NETSTANDARD<x>_<y>_OR_GREATERシンボルは、.NET Core や .NET Framework など、.NET Standard を実装するターゲットではなく、.NET Standard ターゲットに対してのみ定義されます。 - これらは、MSBuild プロパティと NuGet で使用されるターゲット フレームワーク モニカー (TFM) とは異なります。
次に、ターゲットごとに条件付きコンパイルを利用する例を示します。
using System;
using System.Text.RegularExpressions;
#if NET40
// This only compiles for the .NET Framework 4 targets
using System.Net;
#else
// This compiles for all other targets
using System.Net.Http;
using System.Threading.Tasks;
#endif
namespace MultitargetLib
{
public class Library
{
#if NET40
private readonly WebClient _client = new WebClient();
private readonly object _locker = new object();
#else
private readonly HttpClient _client = new HttpClient();
#endif
#if NET40
// .NET Framework 4.0 does not have async/await
public string GetDotNetCount()
{
string url = "https://www.dotnetfoundation.org/";
var uri = new Uri(url);
string result = "";
// Lock here to provide thread-safety.
lock(_locker)
{
result = _client.DownloadString(uri);
}
int dotNetCount = Regex.Matches(result, ".NET").Count;
return $"Dotnet Foundation mentions .NET {dotNetCount} times!";
}
#else
// .NET Framework 4.5+ can use async/await!
public async Task<string> GetDotNetCountAsync()
{
string url = "https://www.dotnetfoundation.org/";
// HttpClient is thread-safe, so no need to explicitly lock here
var result = await _client.GetStringAsync(url);
int dotNetCount = Regex.Matches(result, ".NET").Count;
return $"dotnetfoundation.org mentions .NET {dotNetCount} times in its HTML!";
}
#endif
}
}
を使用してこのプロジェクトをビルドすると、 フォルダー以下に 3 つのディレクトリがあることがわかります。
net40/
net45/
netstandard2.0/
それぞれに各ターゲットの ファイルが含まれています。
.NETでライブラリをテストする方法
プラットフォーム全体でテストできることが重要です。 xUnit または MSTest はそのまま利用できます。 どちらも、.NETでのライブラリの単体テストに最適です。 テスト プロジェクトでソリューションをセットアップする方法は、ソリューションの構造によって異なります。 次の例は、テスト ディレクトリとソース ディレクトリが同じ最上位ディレクトリにある場合です。
注意
これには、いくつかの .NET CLI コマンドが使用されます。 詳細については、「dotnet new」と「dotnet sln」を参照してください。
ソリューションを設定します。 次のコマンドで実行することができます。
mkdir SolutionWithSrcAndTest cd SolutionWithSrcAndTest dotnet new sln dotnet new classlib -o MyProject dotnet new xunit -o MyProject.Test dotnet sln add MyProject/MyProject.csproj dotnet sln add MyProject.Test/MyProject.Test.csprojこれでプロジェクトが作成され、ソリューション内のプロジェクトがリンクされます。 あなたのディレクトリは次のようになります。
/SolutionWithSrcAndTest |__SolutionWithSrcAndTest.sln |__MyProject/ |__MyProject.Test/テスト プロジェクトのディレクトリに移動し、 から への参照を追加します。
cd MyProject.Test dotnet reference add ../MyProject/MyProject.csprojパッケージを復元し、プロジェクトをビルドします。
dotnet restore dotnet buildコマンドを実行して、xUnit が実行されることを確認します。 MSTest を使用する場合は、必ず MSTest コンソール実行ツールが実行されるようにしてください。
以上で作業は終了です。 コマンド ライン ツールを使用して、すべてのプラットフォームでライブラリをテストできるようになりました。 すべてをセットアップしてテストに進む場合、ライブラリのテストはとても単純です。
- ライブラリに変更を加えます。
- コマンド ラインから、 コマンドを使用してテスト ディレクトリでテストを実行します。
コマンドを呼び出すと、コードは自動的にリビルドされます。
複数のプロジェクトを使用する方法
大規模なライブラリで一般的なニーズは、複数のプロジェクトに機能を配置することです。
たとえば、慣用的な C# や F# で使用できるライブラリをビルドするとします。 これは、ライブラリの利用者が C# または F# に自然な形でライブラリを利用することを意味します。 たとえば、C# の場合、次のようにライブラリを使用できます。
using AwesomeLibrary.CSharp;
public Task DoThings(Data data)
{
var convertResult = await AwesomeLibrary.ConvertAsync(data);
var result = AwesomeLibrary.Process(convertResult);
// do something with result
}
F# の場合は次のようになります。
open AwesomeLibrary.FSharp
let doWork data = async {
let! result = AwesomeLibrary.AsyncConvert data // Uses an F# async function rather than C# async method
// do something with result
}
このような使用シナリオは、アクセスされる API が C# と F# 用に異なる構造を持つ必要があることを示します。 これを実現する一般的なアプローチとして、ライブラリのすべてのロジックをコア プロジェクトに取り入れ、C# および F# プロジェクトでコア プロジェクトに呼び出す API レイヤーを定義する方法があります。 以降のセクションでは、次の名前を使用します。
- AwesomeLibrary.Core - ライブラリのすべてのロジックを含むコア プロジェクト
- AwesomeLibrary.CSharp - C# で使用するためのパブリック API を含むプロジェクト
- AwesomeLibrary.FSharp - F# で使用するためのパブリック API を含むプロジェクト
自分のターミナルで次のコマンドを実行し、このガイドと同じ構造を作成することができます。
mkdir AwesomeLibrary && cd AwesomeLibrary
dotnet new sln
mkdir AwesomeLibrary.Core && cd AwesomeLibrary.Core && dotnet new classlib
cd ..
mkdir AwesomeLibrary.CSharp && cd AwesomeLibrary.CSharp && dotnet new classlib
cd ..
mkdir AwesomeLibrary.FSharp && cd AwesomeLibrary.FSharp && dotnet new classlib -lang "F#"
cd ..
dotnet sln add AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
dotnet sln add AwesomeLibrary.CSharp/AwesomeLibrary.CSharp.csproj
dotnet sln add AwesomeLibrary.FSharp/AwesomeLibrary.FSharp.fsproj
これで上記の 3 つのプロジェクトと、それらをリンクするソリューション ファイルが追加されます。 ソリューション ファイルとリンク プロジェクトを作成すると、最上位レベルからプロジェクトを復元し、ビルドできるようになります。
プロジェクト間参照
プロジェクトを参照する最善の方法は、.NET CLI を使用してプロジェクト参照を追加することです。 AwesomeLibrary.CSharp と AwesomeLibrary.FSharp のプロジェクト ディレクトリから、次のコマンドを実行できます。
dotnet reference add ../AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
AwesomeLibrary.CSharp と AwesomeLibrary.FSharp の両方のプロジェクト ファイルは、ターゲットとして AwesomeLibrary.Core を参照するようになります。 この参照を確認するには、プロジェクト ファイルに以下の行があることを確認します。
<ItemGroup>
<ProjectReference Include="..\AwesomeLibrary.Core\AwesomeLibrary.Core.csproj" />
</ItemGroup>
.NET CLI を使用しない場合は、このセクションを各プロジェクト ファイルに手動で追加できます。
ソリューションの構築
マルチプロジェクト ソリューションのもう 1 つの重要な側面は、全体のプロジェクト構造を適切に構築することです。 ただし、 でソリューション ファイルに各プロジェクト ファイルがリンクされ、ソリューション レベルで と を実行できる限り、好みに応じてコードを整理することができます。
.NET