.NET CLI ile kitaplık geliştirme

Bu makalede .NET CLI kullanarak .NET için kitaplık yazma işlemi açıklanır. CLI, desteklenen tüm işletim sisteminde çalışan verimli ve düşük düzeyli bir deneyim sağlar. Visual Studio ile kitaplıklar oluşturmaya devam edebilirsiniz ve tercih ettiğiniz deneyim buysa Visual Studio kılavuzuna bakın.

Önkoşullar

Makinenizde .NET SDK'sının yüklü olması gerekir.

Bu belgenin .NET Framework sürümleriyle ilgili bölümleri için bir Windows makinesinde .NET Framework'ün yüklü olması gerekir.

Ayrıca, eski .NET Framework hedeflerini desteklemek istiyorsanız, .NET Framework indirmeleri sayfasından hedefleme paketleri veya geliştirici paketleri yüklemeniz gerekir. Şu tabloya bakın:

.NET Framework sürümü İndirilmesi gerekenler
4.6.1 .NET Framework 4.6.1 Hedefleme Paketi
4.6 .NET Framework 4.6 Hedefleme Paketi
4.5.2 .NET Framework 4.5.2 Geliştirici Paketi
4.5.1 .NET Framework 4.5.1 Geliştirici Paketi
4,5 Windows 8 için Windows Yazılım Geliştirme Seti
4,0 Windows 7 ve .NET Framework 4 için Windows SDK
2.0, 3.0 ve 3.5 .NET Framework 3.5 SP1 Çalışma Zamanı (veya Windows 8+ sürümü)

.NET 5+ veya .NET Standard'ı hedefleme

Projenizin hedef çerçevesini proje dosyanıza (.csproj veya .fsproj) ekleyerek denetlersiniz. .NET 5+ veya .NET Standard hedeflemesi arasında seçim yapma yönergeleri için bkz . .NET 5+ ve .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 veya sonraki sürümlerini hedeflemek veya .NET Framework'te kullanılabilen ancak .NET Standard'da bulunmayan bir API kullanmak istiyorsanız (örneğin, System.Drawing), aşağıdaki bölümleri okuyun ve çoklu hedeflemeyi öğrenin.

.NET Framework'i hedefleme

Not

Bu yönergelerde makinenizde .NET Framework yüklü olduğu varsayılır. Bağımlılıkları yüklemek için Önkoşullar bölümüne bakın.

Burada kullanılan bazı .NET Framework sürümlerinin artık desteklenmediğini unutmayın. Desteklenmeyen sürümler hakkında .NET Framework Destek Yaşam Döngüsü İlkesi SSS bölümüne bakın.

En fazla geliştirici ve proje sayısına ulaşmak istiyorsanız temel hedefiniz olarak .NET Framework 4.0 kullanın. .NET Framework'i hedeflemek için, desteklemek istediğiniz .NET Framework sürümüne karşılık gelen doğru Target Framework Takma Adını (TFM) kullanarak başlayın.

.NET Framework sürümü 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

Ardından bu TFM'yi TargetFramework proje dosyanızın bölümüne eklersiniz. Örneğin, .NET Framework 4.0'ı hedefleyen bir kitaplığı şöyle yazabilirsiniz:

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

Hepsi bu! Bu yalnızca .NET Framework 4 için derlenmiş olsa da, kitaplığı daha yeni .NET Framework sürümlerinde kullanabilirsiniz.

Çoklu hedefleme

Not

Aşağıdaki yönergelerde makinenizde .NET Framework'ün yüklü olduğu varsayılır. Hangi bağımlılıkları yüklemeniz gerektiğini ve nereden indireceğinizi öğrenmek için Önkoşullar bölümüne bakın.

Projeniz hem .NET Framework hem de .NET'i desteklediğinde .NET Framework'ün eski sürümlerini hedeflemeniz gerekebilir. Bu senaryoda, daha yeni hedefler için daha yeni API'ler ve dil yapıları kullanmak istiyorsanız, kodunuzda yönergeleri kullanın #if . Ayrıca hedeflediğiniz her platform için farklı paketler ve bağımlılıklar ekleyerek her durum için gereken farklı API'leri eklemeniz gerekebilir.

Örneğin, HTTP üzerinden ağ işlemleri gerçekleştiren bir kitaplığınız olduğunu varsayalım. .NET Standard ve .NET Framework sürüm 4.5 veya üzeri için sınıfı ad alanından System.Net.Http kullanabilirsinizHttpClient. Ancak, .NET Framework'ün önceki sürümlerinde sınıfı yokturHttpClient, bu nedenle bunun yerine ad alanından System.Net sınıfını kullanabilirsinizWebClient.

Proje dosyanız şöyle görünebilir:

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

Burada üç önemli değişiklik olduğunu göreceksiniz:

  1. Düğüm TargetFramework ile değiştirildi TargetFrameworksve içinde üç TFM ifade edildi.
  2. Hedef için net40 bir .NET Framework başvurusu çeken bir <ItemGroup> düğüm vardır.
  3. hedef için net45 iki .NET Framework başvurusu çeken bir <ItemGroup> düğüm vardır.

Önişlemci Simgeleri

Derleme sistemi, yönergelerde #if kullanılan aşağıdaki önişlemci sembollerinin farkındadır:

Hedef Çerçeveler Simgeler Ek simgeler
(.NET 5+ SDK'larda kullanılabilir)
Platform simgeleri (yalnızca kullanılabilir)
işletim sistemine özgü bir TFM belirttiğinizde)
.NET Framework NETFRAMEWORK, NET48, NET472, , NET471, NET47, NET462, , NET461, NET46, NET452NET451, NET40NET45, NET35,NET20 NET48_OR_GREATER, , NET471_OR_GREATER, , NET47_OR_GREATER, NET462_OR_GREATER, NET461_OR_GREATER, , NET46_OR_GREATER, NET452_OR_GREATER, NET45_OR_GREATERNET451_OR_GREATER, NET35_OR_GREATERNET40_OR_GREATER, NET472_OR_GREATERNET20_OR_GREATER
.NET Standard NETSTANDARD, , NETSTANDARD2_0NETSTANDARD2_1, , NETSTANDARD1_6, NETSTANDARD1_5, NETSTANDARD1_4, NETSTANDARD1_3, NETSTANDARD1_2, NETSTANDARD1_1,NETSTANDARD1_0 NETSTANDARD2_1_OR_GREATER, NETSTANDARD2_0_OR_GREATER, NETSTANDARD1_6_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+ (ve .NET Core) NET, , NET7_0, , NET6_0, NET5_0, NETCOREAPP, , NETCOREAPP3_1, NETCOREAPP3_0, NETCOREAPP2_1NETCOREAPP2_2, NETCOREAPP1_1NETCOREAPP2_0, NET8_0NETCOREAPP1_0 NET8_0_OR_GREATER, NET7_0_OR_GREATER, , NET6_0_OR_GREATER, NET5_0_OR_GREATER, NETCOREAPP3_1_OR_GREATER, NETCOREAPP3_0_OR_GREATER, , NETCOREAPP2_2_OR_GREATERNETCOREAPP2_1_OR_GREATER, NETCOREAPP2_0_OR_GREATER, NETCOREAPP1_1_OR_GREATER,NETCOREAPP1_0_OR_GREATER ANDROID, BROWSER, IOS, , MACCATALYST, MACOS, TVOS, WINDOWS,
[OS][version] (örneğin IOS15_1),
[OS][version]_OR_GREATER (örneğin IOS15_1_OR_GREATER)

Not

  • Sürümsüz simgeler, hedeflediğiniz sürümden bağımsız olarak tanımlanır.
  • Sürüme özgü simgeler yalnızca hedeflediğiniz sürüm için tanımlanır.
  • Simgeler <framework>_OR_GREATER , hedeflediğiniz sürüm ve önceki tüm sürümler için tanımlanır. Örneğin, .NET Framework 2.0'ı hedef alıyorsanız, şu simgeler tanımlanır: NET20, NET20_OR_GREATER, NET11_OR_GREATERve NET10_OR_GREATER.
  • Simgeler NETSTANDARD<x>_<y>_OR_GREATER yalnızca .NET Standard hedefleri için tanımlanır, .NET Core ve .NET Framework gibi .NET Standard uygulayan hedefler için tanımlanmaz.
  • Bunlar MSBuild TargetFramework özelliği ve NuGet tarafından kullanılan hedef çerçeve adlarından (TFM' ler) farklıdır.

Aşağıda, hedef başına koşullu derlemenin kullanıldığı bir örnek verilmiştir:

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

Bu projeyi ile dotnet buildderlerseniz, klasörünün bin/ altında üç dizin görürsünüz:

net40/
net45/
netstandard2.0/

Bunların her biri her hedefin .dll dosyalarını içerir.

.NET'te kitaplıkları test etme

Platformlar arasında test yapabilmek önemlidir. Kutudan xUnit veya MSTest kullanabilirsiniz. Her ikisi de kitaplığınızı .NET'te birim testi için mükemmel bir şekilde uygundur. Test projeleriyle çözümünüzü nasıl ayarlayacağınız çözümünüzün yapısına bağlıdır. Aşağıdaki örnekte, test ve kaynak dizinlerinin aynı üst düzey dizinde yaşadığı varsayılır.

Not

Bu işlem bazı .NET CLI komutlarını kullanır. Daha fazla bilgi için bkz . dotnet new ve dotnet sln .

  1. Çözümünüzü ayarlayın. Bunu aşağıdaki komutlarla yapabilirsiniz:

    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
    

    Bu işlem proje oluşturur ve bunları bir çözümde birbirine bağlar. dizininiz SolutionWithSrcAndTest şu şekilde görünmelidir:

    /SolutionWithSrcAndTest
    |__SolutionWithSrcAndTest.sln
    |__MyProject/
    |__MyProject.Test/
    
  2. Test projesinin dizinine gidin ve öğesine MyProjectbir başvuru MyProject.Test ekleyin.

    cd MyProject.Test
    dotnet add reference ../MyProject/MyProject.csproj
    
  3. Paketleri ve derleme projelerini geri yükleme:

    dotnet restore
    dotnet build
    
  4. komutunu yürüterek xUnit'in dotnet test çalıştığını doğrulayın. MSTest kullanmayı seçtiyseniz, bunun yerine MSTest konsol çalıştırıcısı çalıştırılmalıdır.

Hepsi bu! Artık komut satırı araçlarını kullanarak kitaplığınızı tüm platformlarda test edebilirsiniz. Her şeyi ayarladığınıza göre test etmeye devam etmek için kitaplığınızı test etmek çok basittir:

  1. Kitaplığınızda değişiklik yapın.
  2. Testleri komut satırından, test dizininizde komutuyla dotnet test çalıştırın.

Komutunu çağırdığınızda dotnet test kodunuz otomatik olarak yeniden oluşturulacaktır.

Birden çok proje kullanma

Daha büyük kitaplıklar için yaygın bir gereksinim, işlevselliği farklı projelere yerleştirmektir.

İdiomatic C# ve F# dilinde kullanılabilecek bir kitaplık oluşturmak istediğinizi düşünün. Bu, kitaplığınızın tüketicilerinin bunu C# veya F# için doğal yollarla tükettiği anlamına gelir. Örneğin, C# dilinde kitaplığı şu şekilde tüketebilirsiniz:

using AwesomeLibrary.CSharp;

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

F# dilinde şu şekilde görünebilir:

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
}

Bunun gibi tüketim senaryoları, erişilen API'lerin C# ve F# için farklı bir yapıya sahip olması anlamına gelir. Bunu başarmak için yaygın bir yaklaşım, C# ve F# projelerinin bu çekirdek projeye çağrıda bulunan API katmanlarını tanımlamasıyla bir kitaplığın tüm mantığını bir çekirdek projede hesaba katmaktır. Bölümün geri kalanında aşağıdaki adlar kullanılır:

  • AwesomeLibrary.Core - Kitaplığın tüm mantığını içeren çekirdek proje
  • AwesomeLibrary.CSharp - C'de tüketime yönelik genel API'leri olan bir proje#
  • AwesomeLibrary.FSharp - F'de tüketime yönelik genel API'leri olan bir proje#

Bu kılavuzla aynı yapıyı oluşturmak için terminalinizde aşağıdaki komutları çalıştırabilirsiniz:

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

Bu, yukarıdaki üç proje ile bunları birbirine bağlayan bir çözüm dosyası ekler. Çözüm dosyasını oluşturma ve projeleri bağlama, projeleri en üst düzeyden geri yüklemenize ve oluşturmanıza olanak sağlar.

Projeden projeye başvuru

Projeye başvurmanın en iyi yolu proje başvurusu eklemek için .NET CLI kullanmaktır. AwesomeLibrary.CSharp ve AwesomeLibrary.FSharp proje dizinlerinden aşağıdaki komutu çalıştırabilirsiniz:

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

Hem AwesomeLibrary.CSharp hem de AwesomeLibrary.FSharp için proje dosyaları artık AwesomeLibrary.Core'a hedef olarak ProjectReference başvuracak. Bunu doğrulamak için proje dosyalarını inceleyebilir ve bunların içinde aşağıdakileri görebilirsiniz:

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

.NET CLI'yi kullanmamak isterseniz bu bölümü her proje dosyasına el ile ekleyebilirsiniz.

Çözümü yapılandırma

Çok projeli çözümlerin bir diğer önemli yönü de iyi bir genel proje yapısı oluşturmaktır. Kodu istediğiniz gibi düzenleyebilirsiniz ve her projeyi ile dotnet sln addçözüm dosyanıza bağladığınız sürece ve dotnet build çözüm düzeyinde çalıştırabilirsinizdotnet restore.