Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek popisuje, jak psát knihovny pro .NET pomocí rozhraní příkazového řádku .NET. Rozhraní CLI poskytuje efektivní a nízkoúrovňové rozhraní, které funguje v jakémkoli podporovaném operačním systému. Knihovny můžete stále vytvářet pomocí Visual Studiem, a pokud je to vaše preferované prostředí, podívejte se na průvodce pro Visual Studio.
Požadavky
Na vašem počítači potřebujete mít nainstalovanou .NET SDK.
V částech tohoto dokumentu, které se zabývají verzemi .NET Framework, potřebujete rozhraní .NET Framework nainstalované na počítači Windows.
Kromě toho, pokud chcete podporovat starší cíle .NET Framework, musíte nainstalovat cílové balíčky nebo vývojářské balíčky ze stránky .NET Framework ke stažení. Projděte si tuto tabulku:
| verze .NET Frameworku | Co stáhnout |
|---|---|
| 4.6.1 | .NET Framework 4.6.1 Targeting Pack |
| 4.6 | .NET Framework 4.6 Cílový balíček |
| 4.5.2 | .NET Framework 4.5.2 Developer Pack |
| 4.5.1 | .NET Framework 4.5.1 Developer Pack (Vývojářský balíček) |
| 4.5 | Windows Software Development Kit pro Windows 8 |
| 4.0 | Windows SDK pro Windows 7 a .NET Framework 4 |
| 2.0, 3.0 a 3.5 | .NET Framework 3.5 SP1 Runtime (nebo verze Windows 8+ |
Jak cílit na .NET 5+ nebo .NET Standard
Cílovou architekturu projektu můžete řídit jeho přidáním do souboru projektu (.csproj nebo .fsproj). Pokyny k výběru mezi cílením na .NET 5 nebo .NET Standard najdete v tématu .NET 5 nebo novější a .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>
Pokud chcete cílit na rozhraní .NET Framework verze 4.0 nebo novější, nebo chcete použít rozhraní API dostupné v .NET Frameworku, ale ne ve standardu .NET (například System.Drawing), přečtěte si následující části a zjistěte, jak multitarget.
Cílení na architekturu .NET
Poznámka:
Tyto pokyny předpokládají, že máte na počítači nainstalovanou .NET Framework. Podívejte se na Požadavky pro instalaci závislostí.
Mějte na paměti, že některé z verzí .NET Framework, které se zde používají, se už nepodporují. Přečtěte si nejčastější dotazy ohledně zásad životního cyklu podpory .NET Framework týkající se nepodporovaných verzí.
Pokud chcete dosáhnout maximálního počtu vývojářů a projektů, použijte jako svůj výchozí cíl .NET Framework 4.0. Pokud chcete cílit na .NET Framework, začněte správným monikerem cílového rozhraní (TFM), který odpovídá verzi .NET Framework, kterou chcete podporovat.
| verze .NET Frameworku | 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 |
Tento TFM pak vložíte do TargetFramework části souboru projektu. Tady je příklad, jak byste napsali knihovnu, která cílí na .NET Framework 4.0:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net40</TargetFramework>
</PropertyGroup>
</Project>
A to je vše! I když je tento kompilovaný pouze pro .NET Framework 4, můžete knihovnu použít v novějších verzích .NET Framework.
Postup cílení na více verzí
Poznámka:
Následující pokyny předpokládají, že máte na počítači nainstalovanou .NET Framework. V části Požadavky se dozvíte, ze kterých závislostí je potřeba nainstalovat a odkud je stáhnout.
Možná budete muset cílit na starší verze .NET Framework, pokud váš projekt podporuje .NET Framework i .NET. Pokud v tomto scénáři chcete pro novější cíle použít novější rozhraní API a jazykové konstrukty, použijte #if ve svém kódu direktivy. Možná budete také muset přidat různé balíčky a závislosti pro každou platformu, na kterou cílíte, aby zahrnovala různá rozhraní API potřebná pro každý případ.
Řekněme například, že máte knihovnu, která provádí síťové operace přes protokol HTTP. Pro .NET Standard a .NET Framework verze 4.5 nebo vyšší můžete použít třídu HttpClient z oboru názvů System.Net.Http. Starší verze .NET Framework však nemají třídu HttpClient, takže byste mohli místo toho použít třídu WebClient z oboru názvů System.Net.
Soubor projektu může vypadat takto:
<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>
Tady si všimnete tří hlavních změn:
- Uzel
TargetFrameworkse nahradilTargetFrameworksa uvnitř jsou vyjádřeny tři TFM. - Pro cíl
net40existuje uzel pro jednu referenci na .NET Framework. - Existuje uzel
<ItemGroup>pro cílnet45, který zahrnuje dvě reference na .NET Framework.
Symboly preprocesoru
Systém sestavení si uvědomuje následující symboly preprocesoru používané ve #if direktivách:
| Cílové architektury | Symboly | Další symboly (k dispozici v .NET 5 a novějších sadách SDK) |
Symboly platformy (k dispozici pouze při zadání TFM specifického pro operační systém) |
|---|---|---|---|
| .NET Framework |
NETFRAMEWORK
NET481
NET48
NET472
NET471
NET47
NET462
NET461
NET46
NET452
NET451
NET45
NET40
NET35
NET20
|
NET48_OR_GREATER, NET472_OR_GREATER, NET471_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_GREATER, NET20_OR_GREATER |
|
| .NET Standard |
NETSTANDARD, NETSTANDARD2_1, NETSTANDARD2_0, 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+ (a také .NET Core) |
NET
NET10_0
NET9_0
NET8_0
NET7_0
NET6_0
NET5_0
NETCOREAPP
NETCOREAPP3_1
NETCOREAPP3_0
NETCOREAPP2_2
NETCOREAPP2_1
NETCOREAPP2_0
NETCOREAPP1_1
NETCOREAPP1_0
|
NET10_0_OR_GREATER, NET9_0_OR_GREATER, 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, , MACCATALYSTMACOS, TVOS, , WINDOWS[OS][version] (například IOS15_1),[OS][version]_OR_GREATER (například IOS15_1_OR_GREATER) |
Poznámka:
- Symboly bez verzí se definují bez ohledu na verzi, na kterou cílíte.
- Symboly specifické pro verzi jsou definované jenom pro verzi, na kterou cílíte.
- Symboly
<framework>_OR_GREATERjsou definované pro verzi, na kterou cílíte, a všechny předchozí verze. Pokud například cílíte na rozhraní .NET Framework 2.0, jsou definovány následující symboly:NET20,NET20_OR_GREATER,NET11_OR_GREATERaNET10_OR_GREATER. - Symboly
NETSTANDARD<x>_<y>_OR_GREATERjsou definovány pouze pro .NET standardní cíle, a ne pro cíle, které implementují .NET Standard, například .NET Core a .NET Framework. - Liší se od cílových rámcových monikerů (TFMs) používaných vlastností MSBuild
TargetFrameworka NuGet.
Tady je příklad použití podmíněné kompilace podle cíle:
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
}
}
Pokud tento projekt sestavíte pomocí dotnet build, všimnete si tří adresářů ve bin/ složce:
net40/
net45/
netstandard2.0/
Každý z těchto souborů obsahuje .dll soubory pro každý cíl.
Testování knihoven na .NET
Je důležité, abyste mohli testovat na různých platformách. Můžete použít buď xUnit, nebo MSTest přímo po instalaci. Oba jsou dokonale vhodné pro testování jednotek knihovny na .NET. Způsob nastavení řešení s testovacími projekty bude záviset na struktuře vašeho řešení. Následující příklad předpokládá, že testovací a zdrojové adresáře žijí ve stejném adresáři nejvyšší úrovně.
Poznámka:
K tomu se používají některé příkazy rozhraní příkazového řádku .NET. Další informace najdete v dotnet new a dotnet sln.
Nastavte řešení. Můžete to udělat pomocí následujících příkazů:
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.csprojTím vytvoříte projekty a propojíte je v řešení. Váš adresář pro
SolutionWithSrcAndTestby měl vypadat takto:/SolutionWithSrcAndTest |__SolutionWithSrcAndTest.sln |__MyProject/ |__MyProject.Test/Přejděte do adresáře testovacího projektu a přidejte odkaz na
MyProject.TestzMyProject.cd MyProject.Test dotnet reference add ../MyProject/MyProject.csprojObnovení balíčků a sestavení projektů:
dotnet restore dotnet buildSpuštěním
dotnet testpříkazu ověřte, že xUnit běží. Pokud jste se rozhodli použít MSTest, měl by se místo toho spustit konsolový běžec MSTest.
A to je vše! Knihovnu teď můžete otestovat na všech platformách pomocí nástrojů příkazového řádku. Pokud chcete pokračovat v testování, když máte všechno nastavené, testování knihovny je velmi jednoduché:
- Proveďte změny v knihovně.
- Pomocí příkazu spusťte testy z příkazového řádku v testovacím
dotnet testadresáři.
Při vyvolání příkazu dotnet test se kód automaticky znovu sestaví.
Jak používat více projektů
Běžnou potřebou větších knihoven je umístit funkce do různých projektů.
Představte si, že chcete vytvořit knihovnu, která by mohla být využita v idiomatických C# a F#. To by znamenalo, že uživatelé vaší knihovny ji využívají způsoby, které jsou přirozené pro C# nebo F#. Například v jazyce C# můžete knihovnu využívat takto:
using AwesomeLibrary.CSharp;
public Task DoThings(Data data)
{
var convertResult = await AwesomeLibrary.ConvertAsync(data);
var result = AwesomeLibrary.Process(convertResult);
// do something with result
}
V jazyce F# to může vypadat takto:
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
}
Scénáře spotřeby, jako je tento, znamenají, že přístupná rozhraní API musí mít jinou strukturu pro C# a F#. Běžným přístupem k tomuto účelu je zohlednit veškerou logiku knihovny do základního projektu pomocí projektů C# a F# definujících vrstvy rozhraní API, které do tohoto základního projektu volají. Zbývající část oddílu bude používat následující názvy:
- AwesomeLibrary.Core – základní projekt, který obsahuje veškerou logiku pro knihovnu
- AwesomeLibrary.CSharp – projekt s veřejnými rozhraními API určenými ke spotřebě v jazyce C#
- AwesomeLibrary.FSharp – projekt s veřejnými rozhraními API určenými ke spotřebě v F#
V terminálu můžete spustit následující příkazy, které vytvoří stejnou strukturu jako v tomto průvodci:
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
Tím se přidají výše uvedené tři projekty a soubor řešení, který je propojí dohromady. Vytvoření souboru řešení a propojení projektů vám umožní obnovit a sestavit projekty z nejvyšší úrovně.
Odkazování mezi projekty
Nejlepším způsobem, jak odkazovat na projekt, je přidat odkaz na projekt pomocí rozhraní příkazového řádku .NET. Z adresářů projektů AwesomeLibrary.CSharp a AwesomeLibrary.FSharp můžete spustit následující příkaz:
dotnet reference add ../AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
Soubory projektu pro AwesomeLibrary.CSharp i AwesomeLibrary.FSharp teď budou odkazovat na AwesomeLibrary.Core jako cíl.ProjectReference Můžete to ověřit kontrolou souborů projektu a zobrazením následujících možností:
<ItemGroup>
<ProjectReference Include="..\AwesomeLibrary.Core\AwesomeLibrary.Core.csproj" />
</ItemGroup>
Pokud nechcete používat rozhraní příkazového řádku .NET CLI, můžete tento oddíl přidat do každého souboru projektu ručně.
Strukturování řešení
Dalším důležitým aspektem řešení s více projekty je vytvoření dobré celkové struktury projektu. Kód můžete uspořádat tak, jak se vám líbí, a pokud každý projekt propojíte se souborem řešení , dotnet sln addbudete moct spouštět dotnet restore a dotnet build na úrovni řešení.