Compartilhar ativos entre clientes web e nativos usando uma RCL (biblioteca de classes) Razor
Observação
Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Use uma RCL (biblioteca de classes) Razor para compartilhar componentes Razor, código C# e ativos estáticos em projetos de cliente Web e nativos.
Este artigo baseia-se nos conceitos gerais encontrados nos seguintes artigos:
- Consumir componentes do Razor de uma Razor biblioteca de classes (RCL)
- Interface do usuário do Razor reutilizável em bibliotecas de classes com o ASP.NET Core
Os exemplos deste artigo compartilham ativos entre um aplicativo Blazor no servidor e um aplicativo .NET MAUIBlazor Hybrid na mesma solução:
- Embora um aplicativo Blazor no servidor seja usado, as diretrizes se aplicam igualmente aos aplicativos Blazor WebAssembly que compartilham ativos com um aplicativo Blazor Hybrid.
- Os projetos estão na mesma solução, mas uma RCL pode fornecer ativos compartilhados para projetos fora de uma solução.
- A RCL é adicionada como um projeto à solução, mas qualquer RCL pode ser publicada como um pacote NuGet. Um pacote NuGet pode fornecer ativos compartilhados para projetos de cliente Web e nativos.
- A ordem em que os projetos são criados não é importante. No entanto, projetos que dependem de uma RCL para ativos devem criar uma referência de projeto à RCL após a criação da RCL.
Para obter orientações sobre a criação de uma RCL, consulte Consumir componentes Razor do ASP.NET Core de uma RCL (biblioteca de classes) Razor. Opcionalmente, acesse as diretrizes adicionais sobre RCLs que se aplicam amplamente a aplicativos ASP.NET Core na Interface do usuário Razor reutilizável em bibliotecas de classes com ASP.NET Core.
Estruturas de destino para implantações do ClickOnce
Para publicar um projeto WPF ou Windows Forms com uma RCL (biblioteca de classes) Razor no .NET 6 com ClickOnce, a RCL deve ter net6.0-windows
como destino, além de net6.0
.
Exemplo:
<TargetFrameworks>net6.0;net6.0-windows</TargetFrameworks>
Para obter mais informações, consulte os seguintes artigos:
Compartilhar componentes da interface do usuário Razor da Web, código e ativos estáticos
Os componentes de uma RCL podem ser compartilhados simultaneamente por aplicativos cliente web e nativos criados usando Blazor. As diretrizes em Consumir componentes ASP.NET Core Razor de uma biblioteca de classes (RCL) Razor explicam como compartilhar componentes Razor usando uma RCL (biblioteca de classes) Razor. As mesmas diretrizes se aplicam à reutilização de componentes Razor de uma RCL em um aplicativo Blazor Hybrid.
Os namespaces de componente são derivados da ID do pacote ou do nome do assembly da RCL e do caminho da pasta do componente na RCL. Para mais informações, confira osComponentes Razor do ASP.NET Core. As diretivas @using
podem ser colocadas em arquivos _Imports.razor
para componentes e código, como demonstra o exemplo a seguir para uma RCL chamada SharedLibrary
com uma pasta Shared
de componentes Razor compartilhados e uma pasta Data
de classes de dados compartilhadas:
@using SharedLibrary
@using SharedLibrary.Shared
@using SharedLibrary.Data
Coloque ativos estáticos compartilhados na pasta wwwroot
da RCL e atualize caminhos de ativo estático no aplicativo para usar o seguinte formato de caminho:
_content/{PACKAGE ID/ASSEMBLY NAME}/{PATH}/{FILE NAME}
Espaços reservados:
{PACKAGE ID/ASSEMBLY NAME}
: a ID do pacote ou o nome do assembly da RCL.{PATH}
: caminho opcional dentro da pastawwwroot
da RCL.{FILE NAME}
: o nome do arquivo do ativo estático.
O formato de caminho anterior também é usado no aplicativo para ativos estáticos fornecidos por um pacote NuGet adicionado à RCL.
Para uma RCL nomeada SharedLibrary
e usando a folha de estilos Bootstrap minimizada como exemplo:
_content/SharedLibrary/css/bootstrap/bootstrap.min.css
Para obter informações adicionais sobre como compartilhar ativos estáticos entre projetos, consulte os seguintes artigos:
- Consumir componentes do Razor de uma Razor biblioteca de classes (RCL)
- Interface do usuário do Razor reutilizável em bibliotecas de classes com o ASP.NET Core
O arquivo raiz index.html
geralmente é específico do aplicativo e deve permanecer no aplicativo Blazor Hybrid ou Blazor WebAssembly. O arquivo index.html
normalmente não é compartilhado.
O componente raiz Razor (App.razor
ou Main.razor
) pode ser compartilhado, mas geralmente pode precisar ser específico para o aplicativo de hospedagem. Por exemplo, App.razor
é diferente nos modelos de projeto Blazor no servidor e Blazor WebAssembly quando a autenticação está habilitada. Você pode adicionar o parâmetro AdditionalAssemblies
para especificar o local de qualquer componente roteável compartilhado e especificar um componente de layout padrão compartilhado para o roteador por nome de tipo.
Fornecer código e serviços independentemente do modelo de hospedagem
Quando o código difere entre modelos de hospedagem ou plataformas de destino, abstraia o código como interfaces e injete as implementações de serviço em cada projeto.
O exemplo de dados meteorológicos a seguir abstrai diferentes implementações do serviço de previsão do tempo:
- Usando uma solicitação HTTP para Blazor Hybrid e Blazor WebAssembly.
- Como solicitar dados diretamente para um aplicativo Blazor no servidor.
O exemplo usa as seguintes especificações e convenções:
- A RCL é nomeada
SharedLibrary
e contém as seguintes pastas e namespaces:Data
: contém a classeWeatherForecast
, que serve como um modelo para dados meteorológicos.Interfaces
: contém a interface de serviço para as implementações de serviço, nomeadaIWeatherForecastService
.
- O componente
FetchData
é mantido na pastaPages
da RCL, que é roteável por qualquer aplicativo que consome a RCL. - Cada aplicativo Blazor mantém uma implementação de serviço que implementa a interface
IWeatherForecastService
.
Data/WeatherForecast.cs
na RCL:
namespace SharedLibrary.Data;
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
Interfaces/IWeatherForecastService.cs
na RCL:
using SharedLibrary.Data;
namespace SharedLibrary.Interfaces;
public interface IWeatherForecastService
{
Task<WeatherForecast[]?> GetForecastAsync(DateTime startDate);
}
O arquivo _Imports.razor
na RCL inclui os seguintes namespaces adicionados:
@using SharedLibrary.Data
@using SharedLibrary.Interfaces
Services/WeatherForecastService.cs
nos aplicativos Blazor Hybrid e Blazor WebAssembly:
using System.Net.Http.Json;
using SharedLibrary.Data;
using SharedLibrary.Interfaces;
namespace {APP NAMESPACE}.Services;
public class WeatherForecastService : IWeatherForecastService
{
private readonly HttpClient http;
public WeatherForecastService(HttpClient http)
{
this.http = http;
}
public async Task<WeatherForecast[]?> GetForecastAsync(DateTime startDate) =>
await http.GetFromJsonAsync<WeatherForecast[]?>("WeatherForecast");
}
No exemplo anterior, o espaço reservado {APP NAMESPACE}
é o namespace do aplicativo.
Services/WeatherForecastService.cs
no aplicativo Blazor no servidor:
using SharedLibrary.Data;
using SharedLibrary.Interfaces;
namespace {APP NAMESPACE}.Services;
public class WeatherForecastService : IWeatherForecastService
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot"
};
public async Task<WeatherForecast[]?> GetForecastAsync(DateTime startDate) =>
await Task.FromResult(Enumerable.Range(1, 5)
.Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
}).ToArray());
}
No exemplo anterior, o espaço reservado {APP NAMESPACE}
é o namespace do aplicativo.
Os aplicativos Blazor Hybrid, Blazor WebAssembly e Blazor no servidor registram as respectivas implementações de serviço de previsão do tempo (Services.WeatherForecastService
) para IWeatherForecastService
.
O projeto Blazor WebAssembly também registra um HttpClient. O HttpClient registrado em um aplicativo criado a partir do modelo de projeto Blazor WebAssembly é suficiente para essa finalidade. Para obter mais informações, consulte Chame uma API Web de um Blazoraplicativo ASP.NET Core.
Pages/FetchData.razor
na RCL:
@page "/fetchdata"
@inject IWeatherForecastService ForecastService
<PageTitle>Weather forecast</PageTitle>
<h1>Weather forecast</h1>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
}
}