Compartilhe ativos entre clientes Web e nativos usando uma biblioteca de classes Razor (RCL)
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Advertência
Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
Importante
Estas informações referem-se a um produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece garantias, expressas ou implícitas, em relação às informações fornecidas aqui.
Para a versão atual, consulte a versão .NET 9 deste artigo.
Use uma biblioteca de classe Razor (RCL) para compartilhar componentes Razor, código C# e ativos estáticos em projetos Web e clientes nativos.
Este artigo baseia-se nos conceitos gerais encontrados nos seguintes artigos:
- Consumir componentes ASP.NET Core Razor de uma biblioteca de classes Razor (RCL)
- Interface do usuário Razor reutilizável em bibliotecas de classe com ASP.NET Core
Os exemplos neste artigo compartilham ativos entre um aplicativo Blazor do lado do servidor e um aplicativo .NET MAUIBlazor Hybrid na mesma solução:
- Embora um aplicativo Blazor do lado do servidor seja usado, as diretrizes se aplicam igualmente a 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 Web e clientes nativos.
- A ordem em que os projetos são criados não é importante. No entanto, os projetos que dependem de um RCL para ativos devem criar uma referência de projeto para o RCL após o RCL for criado.
Para obter orientação sobre como criar uma RCL, consulte Consumir componentes ASP.NET Core Razor de uma biblioteca de classes Razor (RCL). Opcionalmente, acesse as orientações adicionais sobre RCLs que se aplicam amplamente aos aplicativos ASP.NET Core em interface do usuário Razor reutilizável em bibliotecas de classe com ASP.NET Core.
Estruturas de destino para implantações do ClickOnce
Para publicar um projeto WPF ou Windows Forms com uma biblioteca de classes Razor (RCL) no .NET 6 com ClickOnce, a RCL deve ter como alvo net6.0-windows
além de net6.0
.
Exemplo:
<TargetFrameworks>net6.0;net6.0-windows</TargetFrameworks>
Para obter mais informações, consulte os seguintes artigos:
Aplicativo de exemplo
Para obter um exemplo dos cenários descritos neste artigo, consulte o eShop Reference Application (AdventureWorks) (dotnet/eShop
repositório GitHub). O aplicativo .NET MAUIBlazor Hybrid está na pasta src/HybridApp
.
Para obter uma versão do aplicativo de exemplo adaptado para hospedagem do Azure, consulte o repositório Azure-Samples/eShopOnAzure
GitHub.
O aplicativo de exemplo apresenta as seguintes tecnologias:
Partilhar componentes Razor da interface de utilizador da Web, código e recursos estáticos
Os componentes de uma RCL podem ser partilhados simultaneamente por aplicações web e aplicações cliente nativas criadas com Blazor. A orientação em Consumir ASP.NET componentes do Core Razor de uma biblioteca de classes Razor (RCL) explica como compartilhar componentes Razor usando uma biblioteca de classes Razor (RCL). A mesma orientação se aplica à reutilização de componentes Razor de um RCL em um aplicativo Blazor Hybrid.
Os namespaces de componentes são derivados do ID do pacote ou nome do assembly da RCL e do caminho da pasta do componente dentro da RCL. Para obter mais informações, consulte componentes do ASP.NET Core Razor.
@using
diretivas podem ser colocadas em arquivos _Imports.razor
para componentes e código, como o exemplo a seguir demonstra para um RCL chamado SharedLibrary
com uma pasta Shared
de componentes de Razor compartilhados e uma pasta Data
de classes de dados compartilhados:
@using SharedLibrary
@using SharedLibrary.Shared
@using SharedLibrary.Data
Coloque ativos estáticos compartilhados na pasta wwwroot
da RCL e atualize os caminhos de ativos estáticos no aplicativo para usar o seguinte formato de caminho:
_content/{PACKAGE ID/ASSEMBLY NAME}/{PATH}/{FILE NAME}
Marcadores de posição:
-
{PACKAGE ID/ASSEMBLY NAME}
: O ID do pacote ou o nome da assemblagem da RCL. -
{PATH}
: Caminho opcional dentro da pastawwwroot
da RCL. -
{FILE NAME}
: O nome do arquivo do ativo estático.
O formato de caminho mencionado anteriormente também é usado na aplicação para recursos estáticos fornecidos por um pacote NuGet adicionado à RCL.
Para um RCL chamado SharedLibrary
e usando a folha de estilo Bootstrap reduzida 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 ASP.NET Core Razor de uma biblioteca de classes Razor (RCL)
- Interface do usuário Razor reutilizável em bibliotecas de classe com ASP.NET Core
O arquivo de index.html
raiz geralmente é específico para o aplicativo e deve permanecer no aplicativo Blazor Hybrid ou no aplicativo Blazor WebAssembly. O arquivo index.html
normalmente não é compartilhado.
O componente de raiz Razor (App.razor
ou Main.razor
) pode ser partilhado, mas muitas vezes poderá necessitar ser específico para a aplicação de alojamento. Por exemplo, App.razor
é diferente nos modelos de projeto do lado do servidor Blazor 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 pode especificar um componente de layout padrão compartilhado para o roteador por nome de tipo.
Fornecer código e serviços independentes do modelo de hospedagem
Quando o código deve diferir 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 de serviços de previsão do tempo:
- Usando uma solicitação HTTP para Blazor Hybrid e Blazor WebAssembly.
- Solicitar dados diretamente para uma aplicação Blazor do lado do servidor.
O exemplo usa as seguintes especificações e convenções:
- O RCL é chamado
SharedLibrary
e contém as seguintes pastas e namespaces:-
Data
: Contém a classeWeatherForecast
, que serve de modelo para dados meteorológicos. -
Interfaces
: Contém a interface de serviço para as implementações de serviço, denominadaIWeatherForecastService
.
-
- O componente
FetchData
é mantido na pastaPages
da RCL, que é roteável por qualquer um dos aplicativos que consomem 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
no 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 da aplicação.
Services/WeatherForecastService.cs
no aplicativo Blazor do lado do 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 da aplicação.
Os aplicativos Blazor Hybride Blazor WebAssembly, juntamente com o Blazor no lado do servidor, registam as suas implementações dos serviços de previsão do tempo (Services.WeatherForecastService
) para o 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 a partir de uma aplicação ASP.NET Core Blazor.
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);
}
}