Esse artigo aborda como escrever bibliotecas para .NET usando a CLI do .NET. A CLI fornece uma experiência eficiente e de baixo nível que funciona em qualquer sistema operacional com suporte. Você ainda pode criar bibliotecas com o Visual Studio e, se essa for sua experiência preferida, consultar o guia do Visual Studio.
Pré-requisitos
Você precisa do SDK do .NET instalado no seu computador.
Para as seções deste documento que tratam de versões do .NET Framework, é necessário ter o .NET Framework instalado em um computador Windows.
Além disso, se você quiser dar suporte a destinos mais antigos do .NET Framework, precisará instalar pacotes de direcionamento/desenvolvedor na página de arquivos de download do .NET Framework. Consulte esta tabela:
Versão do .NET Framework
O que baixar
4.6.1
Pacote de Direcionamento do .NET Framework 4.6.1
4,6
Pacote de Direcionamento do .NET Framework 4.6
4.5.2
Pacote de Desenvolvedor do .NET Framework 4.5.2
4.5.1
Pacote de Desenvolvedor do .NET Framework 4.5.1
4.5
Software Development Kit do Windows (SDK do Windows) para Windows 8
4,0
SDK do Windows para Windows 7 e .NET Framework 4
2.0, 3.0 e 3.5
Runtime do .NET Framework 3.5 SP1 (ou versão do Windows 8 ou superior)
Como direcionar o .NET 5+ ou o .NET Standard
Você controla a estrutura de destino do projeto adicionando-a ao arquivo de projeto (.csproj ou .fsproj). Para obter diretrizes sobre como escolher entre direcionar o .NET 5+ ou o .NET Standard, consulte .NET 5+ e .NET Standard.
Se desejar direcionar para o .NET Framework versões 4.0 ou inferior, ou se desejar usar uma API disponível no .NET Framework, mas não no .NET Standard (por exemplo, System.Drawing), leia as seções a seguir para aprender a usar multiplataformas.
Como direcionar para o .NET Framework
Observação
Essas instruções pressupõem que você tenha o .NET Framework instalado no seu computador. Consulte os Pré-requisitos para obter as dependências instaladas.
Se desejar alcançar o número máximo de projetos e desenvolvedores, use o .NET Framework 4.0 como seu destino de linha de base. Para direcionar para o .NET Framework, comece usando o TFM (Moniker da Estrutura de Destino) correto correspondente à versão do .NET Framework à qual você deseja dar suporte.
Versão do .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
Em seguida, insira esse TFM na seção TargetFramework do arquivo de projeto. Por exemplo, aqui está como você escreveria uma biblioteca direcionada ao .NET Framework 4.0:
Pronto! Embora seja compilada somente para o .NET Framework 4, você pode usar a biblioteca em versões mais recentes do .NET Framework.
Como usar multiplataformas
Observação
As instruções a seguir pressupõem que você tenha o .NET Framework instalado no seu computador. Consulte a seção Pré-requisitos para saber quais dependências você precisa instalar e de onde baixá-las.
Talvez seja necessário direcionar para versões mais antigas do .NET Framework quando seu projeto der suporte ao .NET Framework e ao .NET. Nesse cenário, se você quiser usar construções de linguagem e APIs mais recentes para os destinos, use as diretivas #if no seu código. Você também pode precisar adicionar diferentes pacotes e dependências para cada plataforma de destino para incluir as diferentes APIs necessárias para cada caso.
Por exemplo, digamos que você tem uma biblioteca que executa operações de rede por meio de HTTP. Para .NET Standard e .NET Framework versões 4.5 ou posterior, você pode usar a classe HttpClient do namespace System.Net.Http. No entanto, versões anteriores do .NET Framework não tem a classe HttpClient, portanto, você pode usar a classe WebClient do namespace System.Net para elas.
O arquivo de projeto seria semelhante a:
XML
<ProjectSdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFrameworks>netstandard2.0;net40;net45</TargetFrameworks></PropertyGroup><!-- Need to conditionally bring in references for the .NET Framework 4.0 target --><ItemGroupCondition="'$(TargetFramework)' == 'net40'"><ReferenceInclude="System.Net" /></ItemGroup><!-- Need to conditionally bring in references for the .NET Framework 4.5 target --><ItemGroupCondition="'$(TargetFramework)' == 'net45'"><ReferenceInclude="System.Net.Http" /><ReferenceInclude="System.Threading.Tasks" /></ItemGroup></Project>
Você notará três alterações importantes aqui:
O nó TargetFramework foi substituído pelo TargetFrameworks e três TFMs são expressas dentro.
Há um nó <ItemGroup> para o destino net40 extraindo um que o .NET Framework referencia.
Há um nó <ItemGroup> para o destino net45 extraindo dois que o .NET Framework referencia.
Símbolos do pré-processador.
O sistema de build reconhece os seguintes símbolos do pré-processador usados nas diretivas #if:
Frameworks de destino
Símbolos
Símbolos adicionais (disponível em SDKs do .NET 5+)
Símbolos de plataforma (disponíveis somente quando você especifica um TFM específico do sistema operacional)
ANDROID, BROWSER, IOS, MACCATALYST, MACOS, TVOS, WINDOWS, [OS][version] (por exemplo, IOS15_1), [OS][version]_OR_GREATER (por exemplo, IOS15_1_OR_GREATER)
Observação
Os símbolos sem versão são definidos independentemente da versão para a qual você está direcionando.
Os símbolos específicos à versão são definidos apenas para a versão que você está direcionando.
Os símbolos <framework>_OR_GREATER são definidos para a versão que você está direcionando e todas as versões anteriores. Por exemplo, se você estiver direcionando .NET Framework 2.0, os seguintes símbolos serão definidos: NET20, NET20_OR_GREATER, NET11_OR_GREATER e NET10_OR_GREATER.
Os símbolos NETSTANDARD<x>_<y>_OR_GREATER são definidos apenas para destinos .NET Standard, e não para destinos que implementam o .NET Standard, como o .NET Core e o .NET Framework.
Aqui está um exemplo fazendo uso de compilação condicional por destino:
C#
using System;
using System.Text.RegularExpressions;
#if NET40// This only compiles for the .NET Framework 4 targetsusing System.Net;
#else// This compiles for all other targetsusing System.Net.Http;
using System.Threading.Tasks;
#endifnamespaceMultitargetLib
{
publicclassLibrary
{
#if NET40privatereadonly WebClient _client = new WebClient();
privatereadonlyobject _locker = newobject();
#elseprivatereadonly HttpClient _client = new HttpClient();
#endif#if NET40// .NET Framework 4.0 does not have async/awaitpublicstringGetDotNetCount()
{
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!publicasync Task<string> GetDotNetCountAsync()
{
string url = "https://www.dotnetfoundation.org/";
// HttpClient is thread-safe, so no need to explicitly lock herevar result = await _client.GetStringAsync(url);
int dotNetCount = Regex.Matches(result, ".NET").Count;
return$"dotnetfoundation.org mentions .NET {dotNetCount} times in its HTML!";
}
#endif
}
}
Se você compilar esse projeto com dotnet build, notará três diretórios sob a pasta bin/:
net40/
net45/
netstandard2.0/
Cada um deles contém arquivos .dll para cada destino.
Como testar bibliotecas no .NET
É importante ser capaz de testar em várias plataformas. Você pode usar o xUnit ou MSTest pronto para uso. Ambos são perfeitamente adequados para realizar o teste da unidade de biblioteca no .NET. A maneira de configurar sua solução com projetos de teste dependerá da estrutura da sua solução. O exemplo a seguir pressupõe que os diretórios de origem e de teste estão no mesmo diretório de nível superior.
Navegue até o diretório do projeto de teste e adicione uma referência a MyProject.Test de MyProject.
CLI do .NET
cd MyProject.Test
dotnetadd reference ../MyProject/MyProject.csproj
Restaure os pacotes e compile projetos:
CLI do .NET
dotnetrestoredotnetbuild
Verifique se o xUnit é executado por meio da execução do comando dotnet test. Se você optar por usar o MSTest, o executor de console do MSTest deverá ser executado.
Pronto! Agora você pode testar sua biblioteca em todas as plataformas usando as ferramentas de linha de comando. É muito simples testar sua biblioteca agora que está tudo configurado:
Faça alterações na sua biblioteca.
Execute os testes de linha de comando no diretório de teste com o comando dotnet test.
Seu código será recriado automaticamente quando você invoca o comando dotnet test.
Como usar vários projetos
Uma necessidade comum das bibliotecas grandes é alocar funcionalidades em diferentes projetos.
Imagine que você deseja compilar uma biblioteca que poderia ser consumida em expressões idiomáticas de C# e F#. Isso significa que os consumidores da sua biblioteca o farão de maneiras naturais ao C# ou ao F#. Por exemplo, você poderia consumir a biblioteca em C# dessa forma:
C#
using AwesomeLibrary.CSharp;
public Task DoThings(Data data)
{
var convertResult = await AwesomeLibrary.ConvertAsync(data);
var result = AwesomeLibrary.Process(convertResult);
// do something with result
}
No F#, ela poderia assemelhar-se a:
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
}
Cenários de consumo como esse significam que as APIs que estão sendo acessadas devem ter uma estrutura diferente para C# e F#. Uma abordagem comum para realizar isso é fatorar toda a lógica de uma biblioteca em um projeto principal, com projetos C# e F# definindo as camadas de API que chamam esse projeto principal. O restante da seção usará os nomes a seguir:
AwesomeLibrary.Core – Um projeto principal que contém toda a lógica para a biblioteca
AwesomeLibrary.CSharp – Um projeto com APIs públicas destinadas ao consumo em C#
AwesomeLibrary.FSharp – Um projeto com APIs públicas destinadas ao consumo em F#
Você pode executar os comandos a seguir no seu terminal para produzir a mesma estrutura que este guia:
CLI do .NET
mkdir AwesomeLibrary && cd AwesomeLibrary
dotnetnewsln
mkdir AwesomeLibrary.Core && cd AwesomeLibrary.Core && dotnetnew classlib
cd ..
mkdir AwesomeLibrary.CSharp && cd AwesomeLibrary.CSharp && dotnetnew classlib
cd ..
mkdir AwesomeLibrary.FSharp && cd AwesomeLibrary.FSharp && dotnetnew classlib -lang"F#"cd ..
dotnetslnadd AwesomeLibrary.Core/AwesomeLibrary.Core.csproj
dotnetslnadd AwesomeLibrary.CSharp/AwesomeLibrary.CSharp.csproj
dotnetslnadd AwesomeLibrary.FSharp/AwesomeLibrary.FSharp.fsproj
Isso adicionará os três projetos acima e um arquivo de solução que os vincula. Criar o arquivo de solução e vincular projetos permitirá que você restaure e compile projetos de um nível superior.
Referência projeto a projeto
A melhor maneira de fazer referência a um projeto é usar a CLI do .NET para adicionar uma referência de projeto. Dos diretórios dos projetos AwesomeLibrary.CSharp e AwesomeLibrary.FSharp, você pode executar o seguinte comando:
Os arquivos de projeto para AwesomeLibrary.CSharp e AwesomeLibrary.FSharp agora farão referência a AwesomeLibrary.Core como um destino ProjectReference. Você pode verificar isso inspecionando os arquivos de projeto e vendo o seguinte neles:
Você pode adicionar esta seção a cada arquivo de projeto manualmente se preferir não usar a CLI do .NET.
Estruturar uma solução
Outro aspecto importante das soluções multiprojetos é estabelecer uma boa estrutura de projeto geral. Você pode organizar o código da maneira que desejar, e desde que vincule cada projeto ao arquivo de solução com dotnet sln add, você poderá executar dotnet restore e dotnet build no nível da solução.
Colaborar conosco no GitHub
A fonte deste conteúdo pode ser encontrada no GitHub, onde você também pode criar e revisar problemas e solicitações de pull. Para obter mais informações, confira o nosso guia para colaboradores.
Comentários do .NET
O .NET é um projeto código aberto. Selecione um link para fornecer comentários:
Crie um projeto do .NET e aprenda a adicionar pacotes e a gerenciar as dependências de pacote no projeto. Use a CLI do .NET Core e o registro do NuGet para adicionar bibliotecas e ferramentas aos aplicativos C# usando o Visual Studio Code.