.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:
- Düğüm
TargetFramework
ile değiştirildiTargetFrameworks
ve içinde üç TFM ifade edildi. - Hedef için
net40
bir .NET Framework başvurusu çeken bir<ItemGroup>
düğüm vardır. - 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 , NET452 NET451 , NET40 NET45 , 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_GREATER NET451_OR_GREATER , NET35_OR_GREATER NET40_OR_GREATER , NET472_OR_GREATER NET20_OR_GREATER |
|
.NET Standard | NETSTANDARD , , NETSTANDARD2_0 NETSTANDARD2_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_1 NETCOREAPP2_2 , NETCOREAPP1_1 NETCOREAPP2_0 , NET8_0 NETCOREAPP1_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_GREATER NETCOREAPP2_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_GREATER
veNET10_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 build
derlerseniz, 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 .
Çö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/
Test projesinin dizinine gidin ve öğesine
MyProject
bir başvuruMyProject.Test
ekleyin.cd MyProject.Test dotnet add reference ../MyProject/MyProject.csproj
Paketleri ve derleme projelerini geri yükleme:
dotnet restore dotnet build
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:
- Kitaplığınızda değişiklik yapın.
- 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
.