Usar APIs ASP.NET Core em uma biblioteca de classes
Por Scott Addie
Este documento fornece orientação para usar ASP.NET APIs principais em uma biblioteca de classes. Para obter todas as outras orientações sobre bibliotecas, consulte Orientações para bibliotecas de código aberto.
Determinar quais versões ASP.NET Core devem ser suportadas
ASP.NET Core segue a política de suporte do .NET Core. Consulte a política de suporte ao determinar quais ASP.NET versões principais a serem suportadas em uma biblioteca. Uma biblioteca deve:
- Faça um esforço para suportar todas as versões do ASP.NET Core classificadas como Long-Term Support (LTS).
- Não se sinta obrigado a suportar ASP.NET versões Core classificadas como de Fim da Vida Útil (EOL).
À medida que as versões de visualização do ASP.NET Core são disponibilizadas, as alterações mais recentes são publicadas no aspnet/Announcements repositório GitHub. Os testes de compatibilidade das bibliotecas podem ser realizados à medida que as funcionalidades do quadro estão a ser desenvolvidas.
Usar a estrutura compartilhada ASP.NET Core
Com o lançamento do .NET Core 3.0, muitos assemblies ASP.NET Core não são mais publicados no NuGet como pacotes. Em vez disso, os assemblies são incluídos na estrutura compartilhada Microsoft.AspNetCore.App
, que é instalada juntamente com o SDK e os instaladores do runtime do .NET Core. Para obter uma lista de pacotes que não estão mais sendo publicados, consulte Remover referências de pacotes obsoletos.
A partir do .NET Core 3.0, os projetos que usam o Microsoft.NET.Sdk.Web
SDK do MSBuild implicitamente fazem referência à estrutura compartilhada. Os projetos que usam o SDK Microsoft.NET.Sdk
ou Microsoft.NET.Sdk.Razor
devem fazer referência ao ASP.NET Core para usar APIs ASP.NET Core na estrutura compartilhada.
Para fazer referência a ASP.NET Core, adicione o seguinte elemento <FrameworkReference>
ao arquivo de projeto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
Incluir Blazor possibilidade de extensão
Blazor oferece suporte à criação de bibliotecas de classes de componentes Razor para aplicativos do lado do servidor e do cliente. Para oferecer suporte a componentes Razor em uma biblioteca de classes, a biblioteca de classes deve usar o Microsoft.NET.Sdk.Razor SDK.
Suporta aplicações do lado do servidor e do lado do cliente
Para suportar o consumo de componentes Razor por aplicações do lado do servidor e do lado cliente de uma única biblioteca, siga as instruções seguintes no seu editor.
- Visual Studio
- Visual Studio Code / .NET CLI
Use o modelo de projeto de Biblioteca de Classes Razor.
Observação
Não marque a caixa de seleção páginas e exibições de suporte. Marcar a caixa de seleção resulta em uma biblioteca de classes que suporta apenas aplicativos do lado do servidor.
A biblioteca gerada a partir do modelo de projeto:
- Serve para direcionar o framework .NET atual com base no SDK instalado.
- Permite a verificação de compatibilidade do navegador para dependências de plataforma, ao incluir
browser
como uma plataforma suportada com o item MSBuildSupportedPlatform
. - Adiciona uma referência de pacote NuGet para Microsoft.AspNetCore.Components.Web .
RazorClassLibrary-CSharp.csproj
(fonte de referência)
Observação
Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para um lançamento específico, use a lista suspensa Mudar ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Suporte a várias versões de framework
Se a biblioteca tiver de suportar funcionalidades adicionadas a Blazor na versão atual e, ao mesmo tempo, suportar uma ou mais versões anteriores, deverá direcionar a biblioteca para vários alvos. Forneça uma lista separada por ponto-e-vírgula de Target Framework Monikers (TFMs) na propriedade TargetFrameworks
MSBuild:
<TargetFrameworks>{TARGET FRAMEWORKS}</TargetFrameworks>
No exemplo anterior, o marcador {TARGET FRAMEWORKS}
representa a lista de TFMs separada por ponto-e-vírgula. Por exemplo, netcoreapp3.1;net5.0
.
Suporta apenas o consumo do lado do servidor
As bibliotecas de classes raramente são criadas para oferecer suporte apenas a aplicativos do lado do servidor. Se a biblioteca de classes exigir apenas recursos específicos do lado do servidor, como acesso a CircuitHandler ou Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage, ou usar recursos específicos do ASP.NET Core, como middleware, controladores MVC ou Razor Pages, use uma das seguintes abordagens:
Especifique que a biblioteca oferece suporte a páginas e modos de exibição quando a biblioteca é criada com a caixa de seleção páginas e modos de exibição de suporte do
(Visual Studio) ou a opção com o comando : dotnet new razorclasslib -s
Forneça apenas uma referência de estrutura para ASP.NET Core no arquivo de projeto da biblioteca, além de quaisquer outras propriedades MSBuild necessárias:
<ItemGroup> <FrameworkReference Include="Microsoft.AspNetCore.App" /> </ItemGroup>
Para obter mais informações sobre bibliotecas que contêm componentes Razor, consulte Consumir componentes ASP.NET Core Razor de uma biblioteca de classes Razor (RCL).
Incluir extensibilidade MVC
Esta seção descreve recomendações para bibliotecas que incluem:
Esta seção não discute a multisegmentação para oferecer suporte a várias versões do MVC. Para obter orientação sobre como suportar várias versões do ASP.NET Core, consulte Suporte a várias versões do ASP.NET Core.
Razor visualizações ou Razor páginas
Um projeto que inclui modos de exibição Razor ou Razor Pages deve usar o Microsoft.NET.Sdk.Razor SDK.
Se o projeto tiver como destino o .NET Core 3.x, ele exigirá:
- Uma propriedade
AddRazorSupportForMvc
MSBuild definida comotrue
. - Um elemento
<FrameworkReference>
para a estrutura partilhada.
O modelo de projeto Razor Biblioteca de Classes satisfaz os requisitos anteriores para projetos destinados ao .NET Core. Use as seguintes instruções para o seu editor.
- Visual Studio
- Código do Visual Studio / Interface de Linha de Comandos (CLI) do .NET
Utilize o modelo de projeto Biblioteca de Classes Razor. A caixa de seleção páginas e visualizações de suporte do modelo deve ser marcada.
Por exemplo:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
Se o projeto tiver como destino o .NET Standard em vez disso, uma referência de pacote Microsoft.AspNetCore.Mvc Microsoft.AspNetCore.Mvc
foi movido para a estrutura compartilhada no ASP.NET Core 3.0 e, portanto, não é mais publicado. Por exemplo:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
</ItemGroup>
</Project>
Ajudantes de tags
Um projeto que inclui Tag Helpers deve usar o Microsoft.NET.Sdk
SDK. Se tiver como destino o .NET Core 3.x, adicione um elemento <FrameworkReference>
para a estrutura compartilhada. Por exemplo:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
Se tiver como destino o .NET Standard (para suportar versões anteriores ao ASP.NET Core 3.x), adicione uma referência de pacote ao Microsoft.AspNetCore.Mvc.Razor. O pacote Microsoft.AspNetCore.Mvc.Razor
passou para o quadro partilhado e, por conseguinte, deixou de ser publicado. Por exemplo:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
</ItemGroup>
</Project>
Ver componentes
Um projeto que inclui componentes View deve usar o Microsoft.NET.Sdk
SDK. Se tiver como destino o .NET Core 3.x, adicione um elemento <FrameworkReference>
para a estrutura compartilhada. Por exemplo:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
Se tiver como destino o .NET Standard (para suportar versões anteriores ao ASP.NET Core 3.x), adicione uma referência de pacote a Microsoft.AspNetCore.Mvc.ViewFeatures. O pacote Microsoft.AspNetCore.Mvc.ViewFeatures
passou para o quadro partilhado e, por conseguinte, deixou de ser publicado. Por exemplo:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
</ItemGroup>
</Project>
Suporta várias versões ASP.NET Core
A multisegmentação é necessária para criar uma biblioteca que ofereça suporte a várias variantes do ASP.NET Core. Considere um cenário no qual uma biblioteca de Ajudantes de Tag deve oferecer suporte às seguintes variantes ASP.NET Core:
- ASP.NET Core 2.1 visando o .NET Framework 4.6.1
- ASP.NET Core 2.x visando o .NET Core 2.x
- ASP.NET Core 3.x visando o .NET Core 3.x
O seguinte arquivo de projeto suporta essas variantes por meio da propriedade TargetFrameworks
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net461</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.16.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
Com o arquivo de projeto anterior:
- O pacote
Markdig
é adicionado para todos os consumidores. - Uma referência a Microsoft.AspNetCore.Mvc.Razor é adicionada para consumidores que usam o .NET Framework 4.6.1 ou posterior, ou o .NET Core 2.x. A versão 2.1.0 do pacote funciona com o ASP.NET Core 2.2 devido à compatibilidade com versões anteriores.
- A estrutura compartilhada é referenciada para consumidores que visam o .NET Core 3.x. O pacote
Microsoft.AspNetCore.Mvc.Razor
está incluído no quadro partilhado.
Como alternativa, pode-se optar por alvo o .NET Standard 2.0 em vez de direcionar tanto o .NET Core 2.1 quanto o .NET Framework 4.6.1.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.16.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
Com o arquivo de projeto anterior, existem as seguintes advertências:
- Como a biblioteca contém apenas Tag Helpers, é mais simples direcionar as plataformas específicas nas quais o ASP.NET Core é executado: .NET Core e .NET Framework. Os Auxiliares de Tags não podem ser usados por outras estruturas de destino compatíveis com o .NET Standard 2.0, como Unity e UWP.
- Usar o .NET Standard 2.0 do .NET Framework tem alguns problemas que foram abordados no .NET Framework 4.7.2. Você pode melhorar a experiência dos consumidores usando o .NET Framework 4.6.1 a 4.7.1 direcionando o .NET Framework 4.6.1.
Se sua biblioteca precisar chamar APIs específicas da plataforma, direcione implementações .NET específicas em vez do .NET Standard. Para obter mais informações, consulte Multi-targeting.
Use uma API que não foi alterada
Imagine um cenário em que você está atualizando uma biblioteca de middleware do .NET Core 2.2 para 3.1. As APIs de middleware do ASP.NET Core que estão sendo usadas na biblioteca não foram alteradas entre ASP.NET Core 2.2 e 3.1. Para continuar a oferecer suporte à biblioteca de middleware no .NET Core 3.1, execute as seguintes etapas:
- Siga as orientações da biblioteca padrão.
- Adicione uma referência de pacote para cada pacote NuGet da API se o assembly correspondente não existir na estrutura compartilhada.
Usar uma API alterada
Imagine um cenário no qual você está atualizando uma biblioteca do .NET Core 2.2 para o .NET Core 3.1. Uma API ASP.NET Core que está sendo usada na biblioteca tem uma alteração significativa no ASP.NET Core 3.1. Considere se a biblioteca pode ser reescrita para não usar a API quebrada em todas as versões.
Se você puder reescrever a biblioteca, faça isso e continue a direcionar uma estrutura de destino anterior (por exemplo, .NET Standard 2.0 ou .NET Framework 4.6.1) com referências de pacote.
Se não conseguir reescrever a biblioteca, siga os seguintes passos:
- Adicione um destino para o .NET Core 3.1.
- Adicione um elemento
<FrameworkReference>
para a estrutura compartilhada. - Use a diretiva de pré-processador #if com o símbolo de estrutura de destino apropriado para compilar condicionalmente o código.
Por exemplo, leituras e gravações síncronas em fluxos de solicitação e resposta HTTP são desabilitadas por padrão a partir do ASP.NET Core 3.1. ASP.NET Core 2.2 suporta o comportamento síncrono por padrão. Considere uma biblioteca de middleware na qual leituras e gravações síncronas devem ser habilitadas onde a E/S está ocorrendo. A biblioteca deve incluir o código para habilitar recursos síncronos na diretiva de pré-processador apropriada. Por exemplo:
public async Task Invoke(HttpContext httpContext)
{
if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
{
httpContext.Response.StatusCode = (int) HttpStatusCode.OK;
httpContext.Response.ContentType = "application/json";
httpContext.Response.ContentLength = _bufferSize;
#if !NETCOREAPP3_1 && !NETCOREAPP5_0
var syncIOFeature = httpContext.Features.Get<IHttpBodyControlFeature>();
if (syncIOFeature != null)
{
syncIOFeature.AllowSynchronousIO = true;
}
using (var sw = new StreamWriter(
httpContext.Response.Body, _encoding, bufferSize: _bufferSize))
{
_json.Serialize(sw, new JsonMessage { message = "Hello, World!" });
}
#else
await JsonSerializer.SerializeAsync<JsonMessage>(
httpContext.Response.Body, new JsonMessage { message = "Hello, World!" });
#endif
return;
}
await _next(httpContext);
}
Usar uma API introduzida na versão 3.1
Imagine que você deseja usar uma API ASP.NET Core que foi introduzida no ASP.NET Core 3.1. Considere as seguintes perguntas:
- A biblioteca requer funcionalmente a nova API?
- A biblioteca pode implementar esse recurso de uma maneira diferente?
Se a biblioteca exigir funcionalmente a API e não houver como implementá-la no nível inferior:
- Destine-se apenas ao .NET Core 3.x.
- Adicione um elemento
<FrameworkReference>
para a estrutura compartilhada.
Se a biblioteca puder implementar o recurso de uma maneira diferente:
- Adicione o .NET Core 3.x como uma estrutura de destino.
- Adicione um elemento
<FrameworkReference>
para a estrutura compartilhada. - Use a diretiva de pré-processador #if com o símbolo de estrutura de destino apropriado para compilar condicionalmente o código.
Por exemplo, o Tag Helper a seguir usa a interface IWebHostEnvironment introduzida no ASP.NET Core 3.1. Os consumidores que visam o .NET Core 3.1 executam o caminho de código definido pelo símbolo da estrutura de destino NETCOREAPP3_1
. O tipo de parâmetro do construtor Tag Helper muda para IHostingEnvironment para consumidores do .NET Core 2.1 e do .NET Framework 4.6.1. Essa mudança foi necessária porque ASP.NET Core 3.1 marcou IHostingEnvironment
como obsoleta e recomendou IWebHostEnvironment
como a substituição.
[HtmlTargetElement("script", Attributes = "asp-inline")]
public class ScriptInliningTagHelper : TagHelper
{
private readonly IFileProvider _wwwroot;
#if NETCOREAPP3_1
public ScriptInliningTagHelper(IWebHostEnvironment env)
#else
public ScriptInliningTagHelper(IHostingEnvironment env)
#endif
{
_wwwroot = env.WebRootFileProvider;
}
// code omitted for brevity
}
O seguinte ficheiro de projeto multi-alvo oferece suporte a este cenário de Tag Helper.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net461</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.16.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
Usar uma API removida da estrutura compartilhada
Para usar um assembly ASP.NET Core que foi removido da estrutura compartilhada, adicione a referência de pacote apropriada. Para obter uma lista de pacotes removidos da estrutura compartilhada no ASP.NET Core 3.1, consulte Remover referências de pacotes obsoletos.
Por exemplo, para adicionar o cliente de API da Web:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
</ItemGroup>
</Project>