Bagikan melalui


Mengembangkan pustaka dengan .NET CLI

Artikel ini membahas cara menulis pustaka untuk .NET menggunakan .NET CLI. CLI memberikan pengalaman efisien dan tingkat rendah yang berfungsi di semua OS yang didukung. Anda masih dapat membuat pustaka dengan Visual Studio, dan jika itu adalah pengalaman pilihan Anda, lihat panduan Visual Studio.

Prasyarat

Anda memerlukan .NET SDK yang terinstal di komputer Anda.

Untuk bagian dokumen ini yang berurusan dengan versi .NET Framework, Anda memerlukan .NET Framework yang diinstal pada komputer Windows.

Selain itu, jika Anda ingin mendukung target .NET Framework yang lebih lama, Anda perlu menginstal paket penargetan atau paket pengembang dari halaman unduhan .NET Framework. Lihat tabel ini:

Versi .NET Framework Apa yang harus diunduh
4.6.1 Paket Penargetan .NET Framework 4.6.1
4.6 Paket Penargetan .NET Framework 4.6
4.5.2 Paket Pengembang .NET Framework 4.5.2
4.5.1 Paket Pengembang .NET Framework 4.5.1
4.5 Kit Pengembangan Perangkat Lunak Windows untuk Windows 8
4,0 Windows SDK untuk Windows 7 dan .NET Framework 4
2.0, 3.0, dan 3.5 Runtime .NET Framework 3.5 SP1 (atau versi Windows 8+)

Cara menargetkan .NET 5+ atau .NET Standard

Anda mengontrol kerangka kerja target proyek dengan menambahkannya ke file proyek Anda (.csproj atau .fsproj). Untuk panduan tentang cara memilih antara penargetan .NET 5+ atau .NET Standard, lihat .NET 5+ dan .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>

Jika Anda ingin menargetkan .NET Framework versi 4.0 atau di bawahnya, atau Anda ingin menggunakan API yang tersedia di .NET Framework tetapi tidak di .NET Standard (misalnya, System.Drawing), baca bagian berikut dan pelajari cara melakukan multitarget.

Cara menargetkan .NET Framework

Catatan

Instruksi ini mengasumsikan Anda memiliki .NET Framework yang terinstal di komputer Anda. Lihat Prasyarat untuk menginstal dependensi.

Perlu diingat bahwa beberapa versi .NET Framework yang digunakan di sini tidak lagi didukung. Lihat FAQ Kebijakan Siklus Hidup Dukungan .NET Framework tentang versi yang tidak didukung.

Jika Anda ingin mencapai jumlah maksimum pengembang dan proyek, gunakan .NET Framework 4.0 sebagai target dasar Anda. Untuk menargetkan .NET Framework, mulailah dengan menggunakan Moniker Kerangka Kerja Target (TFM) yang benar yang sesuai dengan versi .NET Framework yang ingin Anda dukung.

Versi .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

Anda kemudian menyisipkan TFM ini ke bagian TargetFramework file proyek Anda. Misalnya, berikut adalah cara Anda menulis pustaka yang menargetkan .NET Framework 4.0:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net40</TargetFramework>
  </PropertyGroup>
</Project>

Dan itu saja! Meskipun ini dikompilasi hanya untuk .NET Framework 4, Anda dapat menggunakan pustaka pada versi .NET Framework yang lebih baru.

Cara multitarget

Catatan

Instruksi berikut mengasumsikan Bahwa Anda memiliki .NET Framework yang terinstal di komputer Anda. Lihat bagian Prasyarat untuk mempelajari dependensi mana yang perlu Anda instal dan tempat mengunduhnya.

Anda mungkin perlu menargetkan versi .NET Framework yang lebih lama saat proyek Anda mendukung .NET Framework dan .NET. Dalam skenario ini, jika Anda ingin menggunakan API dan konstruksi bahasa yang lebih baru untuk target yang lebih baru, gunakan #if arahan dalam kode Anda. Anda mungkin juga perlu menambahkan paket dan dependensi yang berbeda untuk setiap platform yang Anda targetkan untuk menyertakan BERBAGAI API yang diperlukan untuk setiap kasus.

Misalnya, Anda memiliki pustaka yang melakukan operasi jaringan melalui HTTP. Untuk .NET Standard dan .NET Framework versi 4.5 atau yang lebih tinggi, Anda dapat menggunakan HttpClient kelas dari System.Net.Http namespace. Namun, versi .NET Framework yang lebih lama tidak memiliki HttpClient kelas , sehingga Anda dapat menggunakan WebClient kelas dari System.Net namespace layanan untuk itu sebagai gantinya.

File proyek Anda bisa terlihat seperti ini:

<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>

Anda akan melihat tiga perubahan besar di sini:

  1. Simpul TargetFramework telah digantikan oleh TargetFrameworks, dan tiga TFM dinyatakan di dalamnya.
  2. Ada simpul <ItemGroup> untuk target yang net40 menarik dalam satu referensi .NET Framework.
  3. Ada simpul <ItemGroup> untuk target yang net45 menarik dalam dua referensi .NET Framework.

Simbol Praprosesor

Sistem build mengetahui simbol praprosesor berikut yang digunakan dalam #if arahan:

Kerangka Kerja Target Simbol Simbol tambahan
(tersedia dalam .NET 5+ SDK)
Simbol platform (hanya tersedia
saat Anda menentukan TFM khusus OS)
.NET Framework NETFRAMEWORK, , NET472NET48, NET471, NET47, NET462, NET461, NET46, NET452, NET451, NET45, NET40, , , NET35NET20 NET48_OR_GREATER, , NET472_OR_GREATERNET471_OR_GREATER, NET47_OR_GREATER, NET462_OR_GREATER, NET461_OR_GREATER, NET46_OR_GREATER, NET452_OR_GREATER, NET451_OR_GREATER, NET45_OR_GREATER, , NET40_OR_GREATER, , NET35_OR_GREATERNET20_OR_GREATER
.NET Standar NETSTANDARD, , NETSTANDARD2_1NETSTANDARD2_0, NETSTANDARD1_6, NETSTANDARD1_5, NETSTANDARD1_4, NETSTANDARD1_3, NETSTANDARD1_2, , NETSTANDARD1_1,NETSTANDARD1_0 NETSTANDARD2_1_OR_GREATER, , NETSTANDARD1_6_OR_GREATERNETSTANDARD2_0_OR_GREATER, NETSTANDARD1_5_OR_GREATER, NETSTANDARD1_4_OR_GREATER, NETSTANDARD1_3_OR_GREATER, NETSTANDARD1_2_OR_GREATER, , NETSTANDARD1_1_OR_GREATER,NETSTANDARD1_0_OR_GREATER
.NET 5+ (dan .NET Core) NET, , NET8_0NET7_0, NET6_0, NET5_0, NETCOREAPP, NETCOREAPP3_1, NETCOREAPP3_0, NETCOREAPP2_2, NETCOREAPP2_1, , NETCOREAPP2_0, , NETCOREAPP1_1NETCOREAPP1_0 NET8_0_OR_GREATER, , NET7_0_OR_GREATERNET6_0_OR_GREATER, NET5_0_OR_GREATER, NETCOREAPP3_1_OR_GREATER, NETCOREAPP3_0_OR_GREATER, NETCOREAPP2_2_OR_GREATER, NETCOREAPP2_1_OR_GREATER, NETCOREAPP2_0_OR_GREATER, , , NETCOREAPP1_1_OR_GREATERNETCOREAPP1_0_OR_GREATER ANDROID, , IOSBROWSER, MACCATALYST, MACOS, TVOS, , WINDOWS,
[OS][version] (misalnya IOS15_1),
[OS][version]_OR_GREATER (misalnya IOS15_1_OR_GREATER)

Catatan

  • Simbol tanpa versi ditentukan terlepas dari versi yang Anda targetkan.
  • Simbol khusus versi hanya ditentukan untuk versi yang Anda targetkan.
  • Simbol <framework>_OR_GREATER ditentukan untuk versi yang Anda targetkan dan semua versi sebelumnya. Misalnya, jika Anda menargetkan .NET Framework 2.0, simbol berikut ditentukan: NET20, NET20_OR_GREATER, NET11_OR_GREATER, dan NET10_OR_GREATER.
  • Simbol NETSTANDARD<x>_<y>_OR_GREATER hanya didefinisikan untuk target .NET Standard, dan bukan untuk target yang mengimplementasikan .NET Standard, seperti .NET Core dan .NET Framework.
  • Ini berbeda dari moniker kerangka kerja target (TFM) yang digunakan oleh properti MSBuild TargetFramework dan NuGet.

Berikut adalah contoh penggunaan kompilasi bersyarah per target:

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
    }
}

Jika Anda membangun proyek ini dengan dotnet build, Anda akan melihat tiga direktori di bin/ bawah folder:

net40/
net45/
netstandard2.0/

Masing-masing berisi .dll file untuk setiap target.

Cara menguji pustaka di .NET

Penting untuk dapat menguji di seluruh platform. Anda dapat menggunakan xUnit atau MSTest di luar kotak. Keduanya sangat cocok untuk unit yang menguji pustaka Anda di .NET. Cara Anda menyiapkan solusi dengan proyek pengujian akan bergantung pada struktur solusi Anda. Contoh berikut mengasumsikan bahwa direktori pengujian dan sumber berada di direktori tingkat atas yang sama.

Catatan

Ini menggunakan beberapa perintah .NET CLI . Lihat dotnet baru dan dotnet sln untuk informasi selengkapnya.

  1. Siapkan solusi Anda. Anda dapat melakukannya dengan perintah berikut:

    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
    

    Ini akan membuat proyek dan menautkannya bersama-sama dalam solusi. Direktori Anda untuk SolutionWithSrcAndTest akan terlihat seperti ini:

    /SolutionWithSrcAndTest
    |__SolutionWithSrcAndTest.sln
    |__MyProject/
    |__MyProject.Test/
    
  2. Navigasi ke direktori proyek pengujian dan tambahkan referensi ke MyProject.Test dari MyProject.

    cd MyProject.Test
    dotnet add reference ../MyProject/MyProject.csproj
    
  3. Pulihkan paket dan bangun proyek:

    dotnet restore
    dotnet build
    
  4. Verifikasi bahwa xUnit berjalan dengan menjalankan dotnet test perintah . Jika Anda memilih untuk menggunakan MSTest, maka runner konsol MSTest harus berjalan sebagai gantinya.

Dan itu saja! Anda sekarang dapat menguji pustaka Anda di semua platform menggunakan alat baris perintah. Untuk melanjutkan pengujian sekarang setelah Anda menyiapkan semuanya, menguji pustaka Anda sangat sederhana:

  1. Buat perubahan pada pustaka Anda.
  2. Jalankan pengujian dari baris perintah, di direktori pengujian Anda, dengan dotnet test perintah.

Kode Anda akan dibangun kembali secara otomatis saat Anda memanggil dotnet test perintah.

Cara menggunakan beberapa proyek

Kebutuhan umum untuk pustaka yang lebih besar adalah menempatkan fungsionalitas dalam proyek yang berbeda.

Bayangkan Anda ingin membangun pustaka yang dapat dikonsumsi dalam C# idiomatik dan F#. Itu berarti bahwa konsumen pustaka Anda menggunakannya dengan cara yang alami untuk C# atau F#. Misalnya, di C# Anda mungkin menggunakan pustaka seperti ini:

using AwesomeLibrary.CSharp;

public Task DoThings(Data data)
{
    var convertResult = await AwesomeLibrary.ConvertAsync(data);
    var result = AwesomeLibrary.Process(convertResult);
    // do something with result
}

Di F#, mungkin terlihat seperti ini:

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
}

Skenario konsumsi seperti ini berarti bahwa API yang diakses harus memiliki struktur yang berbeda untuk C# dan F#. Pendekatan umum untuk mencapai hal ini adalah dengan memperhitungkan semua logika pustaka ke dalam proyek inti, dengan proyek C# dan F# yang menentukan lapisan API yang memanggil ke proyek inti tersebut. Bagian lainnya akan menggunakan nama berikut:

  • AwesomeLibrary.Core - Proyek inti yang berisi semua logika untuk pustaka
  • AwesomeLibrary.CSharp - Proyek dengan API publik yang ditujukan untuk konsumsi di C#
  • AwesomeLibrary.FSharp - Proyek dengan API publik yang ditujukan untuk konsumsi di F#

Anda dapat menjalankan perintah berikut di terminal Anda untuk menghasilkan struktur yang sama dengan panduan ini:

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

Ini akan menambahkan tiga proyek di atas dan file solusi yang menautkannya bersama-sama. Membuat file solusi dan menautkan proyek akan memungkinkan Anda memulihkan dan membangun proyek dari tingkat atas.

Referensi proyek-ke-proyek

Cara terbaik untuk mereferensikan proyek adalah dengan menggunakan .NET CLI untuk menambahkan referensi proyek. Dari direktori proyek AwesomeLibrary.CSharp dan AwesomeLibrary.FSharp, Anda dapat menjalankan perintah berikut:

dotnet add reference ../AwesomeLibrary.Core/AwesomeLibrary.Core.csproj

File proyek untuk AwesomeLibrary.CSharp dan AwesomeLibrary.FSharp sekarang akan mereferensikan AwesomeLibrary.Core sebagai ProjectReference target. Anda dapat memverifikasi ini dengan memeriksa file proyek dan melihat yang berikut ini di dalamnya:

<ItemGroup>
  <ProjectReference Include="..\AwesomeLibrary.Core\AwesomeLibrary.Core.csproj" />
</ItemGroup>

Anda dapat menambahkan bagian ini ke setiap file proyek secara manual jika Anda lebih suka tidak menggunakan .NET CLI.

Menyusun solusi

Aspek penting lainnya dari solusi multi-proyek adalah membangun struktur proyek keseluruhan yang baik. Anda dapat mengatur kode sesuka Anda, dan selama Anda menautkan setiap proyek ke file solusi Anda dengan dotnet sln add, Anda akan dapat menjalankan dotnet restore dan dotnet build pada tingkat solusi.