Consumir componentes Razor do ASP.NET Core de uma biblioteca de classes (RCL) Razor
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.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 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 a versão atual, consulte a versão .NET 9 deste artigo.
Os componentes podem ser compartilhados em uma biblioteca de classes Razor(RCL) entre projetos. Inclua componentes e ativos estáticos em um aplicativo de:
- Outro projeto na solução.
- Uma biblioteca .NET de referência.
- Um pacote NuGet.
Assim como os componentes são tipos regulares do .NET, os componentes fornecidos por uma RCL são assemblies .NET normais.
Criar uma RCL
- Criar um novo projeto.
- Na caixa de diálogo Criar um novo projeto, selecione Biblioteca de ClassesRazor na lista de modelos de projeto ASP.NET Core. Selecione Avançar.
- Na caixa de diálogo Configurar seu novo projeto, forneça um nome de projeto no campo Nome do projeto. Exemplos neste tópico usam o nome do projeto
ComponentLibrary
. Selecione Avançar. - Na caixa de diálogo Informações adicionais, não selecione Páginas de suporte e exibições. Selecione Criar.
- Adicione a RCL a uma solução:
- Abrir a solução.
- No Gerenciador de Soluções, clique com o botão direito do mouse na solução. Selecione Adicionar>Projeto Existente.
- Navegue até o arquivo de projeto da RCL.
- Selecione o arquivo de projeto da RCL (
.csproj
).
- Adicione uma referência à RCL do aplicativo:
- Clique com o botão direito do mouse no aplicativo. Selecione Adicionar>Referência de projeto.
- Selecione o projeto da RCL. Selecione OK.
Consumo de um componente Razor de uma RCL
Para consumir componentes de uma RCL em outro projeto, use uma das seguintes abordagens:
- Use o nome completo do tipo de componente, que inclui o namespace da RCL.
- Componentes individuais podem ser adicionados pelo nome sem o namespace da RCL se a diretivaRazor da
@using
declara o namespace da RCL. Use uma das abordagens a seguir:- Adicionar a diretiva
@using
a componentes individuais. - incluir a diretiva
@using
no arquivo_Imports.razor
de nível superior para disponibilizar os componentes da biblioteca para um projeto inteiro. Adicione a diretiva a um arquivo_Imports.razor
em qualquer nível para aplicar o namespace a um único componente ou conjunto de componentes dentro de uma pasta. Quando um arquivo_Imports.razor
é usado, componentes individuais não exigem uma diretiva@using
para o namespace da RCL.
- Adicionar a diretiva
Nos exemplos a seguir, ComponentLibrary
é uma RCL que contém o componente Component1
. O componente Component1
é um componente de exemplo adicionado automaticamente a uma RCL criada com base no modelo de projeto RCL que não é criado para dar suporte a páginas e visualizações.
Component1.razor
na RCL ComponentLibrary
:
<div class="my-component">
This component is defined in the <strong>ComponentLibrary</strong> package.
</div>
No aplicativo que consome a RCL, faça referência ao componente Component1
usando seu namespace, como mostra o exemplo a seguir.
ConsumeComponent1.razor
:
@page "/consume-component-1"
<h1>Consume component (full namespace example)</h1>
<ComponentLibrary.Component1 />
Como alternativa, adicione uma diretiva @using
e use o componente sem seu namespace. A diretiva @using
a seguir também pode aparecer em qualquer arquivo _Imports.razor
na pasta atual ou acima dela.
ConsumeComponent2.razor
:
@page "/consume-component-2"
@using ComponentLibrary
<h1>Consume component (<code>@@using</code> example)</h1>
<Component1 />
Para componentes de biblioteca que usam isolamento de CSS, os estilos de componente são disponibilizados automaticamente para o aplicativo de consumo. Não é necessário vincular ou importar manualmente as folhas de estilos de componentes individuais da biblioteca ou seu arquivo CSS agrupado no aplicativo que consome a biblioteca. O aplicativo usa importações CSS para fazer referência aos estilos agrupados da RCL. Os estilos agrupados da RCL não serão publicados como um ativo da Web estático do aplicativo que consome os estilos. Para uma biblioteca de classes chamada ClassLib
e um aplicativo Blazor com uma folha de estilos BlazorSample.styles.css
, a folha de estilos da RCL é importada na parte superior da folha de estilos do aplicativo automaticamente no tempo de compilação:
@import '_content/ClassLib/ClassLib.bundle.scp.css';
Para os exemplos anteriores, a folha de estilos de Component1
(Component1.razor.css
) é agrupada automaticamente.
Component1.razor.css
na RCL de ComponentLibrary
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
A imagem em segundo plano também está incluída no modelo de projeto RCL e fica na pasta wwwroot
da RCL.
wwwroot/background.png
na RCL de ComponentLibrary
:
Para fornecer estilos de componente de biblioteca adicionais de folhas de estilos na pasta wwwroot
da biblioteca, adicione marcas <link>
na folha de estilo ao consumidor da RCL, como mostra o próximo exemplo.
Importante
Em geral, os componentes da biblioteca usam o isolamento de CSS para agrupar e fornecer estilos de componente. Os estilos de componente que dependem do isolamento de CSS estão disponíveis automaticamente para o aplicativo que usa a RCL. Não é necessário vincular ou importar manualmente as folhas de estilos de componentes individuais da biblioteca ou seu arquivo CSS agrupado no aplicativo que consome a biblioteca. O exemplo a seguir mostra folhas de estilo globais fora do isolamento de CSS, o que geralmente não é um requisito para aplicativos típicos que consomem RCLs.
A imagem em segundo plano a seguir é usada no próximo exemplo. Se você implementar o exemplo mostrado nesta seção, clique com o botão direito do mouse na imagem para salvá-la localmente.
wwwroot/extra-background.png
na RCL de ComponentLibrary
:
Adicione uma nova folha de estilos à RCL com uma extra-style
classe .
wwwroot/additionalStyles.css
na RCL de ComponentLibrary
:
.extra-style {
border: 2px dashed blue;
padding: 1em;
margin: 1em 0;
background-image: url('extra-background.png');
}
Adicione um componente à RCL que usa a classe extra-style
.
ExtraStyles.razor
na RCL de ComponentLibrary
:
<div class="extra-style">
<p>
This component is defined in the <strong>ComponentLibrary</strong> package.
</p>
</div>
Adicione uma página ao aplicativo que usa o componente ExtraStyles
da RCL.
ConsumeComponent3.razor
:
@page "/consume-component-3"
@using ComponentLibrary
<h1>Consume component (<code>additionalStyles.css</code> example)</h1>
<ExtraStyles />
Link para a folha de estilos da biblioteca na marcação <head>
do aplicativo (local do conteúdo <head>
):
Blazor Web Apps:
<link href="@Assets["_content/ComponentLibrary/additionalStyles.css"]" rel="stylesheet">
Aplicativos Blazor WebAssembly autônomos:
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
Para componentes de biblioteca que usam isolamento de CSS, os estilos de componente são disponibilizados automaticamente para o aplicativo de consumo. Não é necessário vincular ou importar manualmente as folhas de estilos de componentes individuais da biblioteca ou seu arquivo CSS agrupado no aplicativo que consome a biblioteca. O aplicativo usa importações CSS para fazer referência aos estilos agrupados da RCL. Os estilos agrupados da RCL não serão publicados como um ativo da Web estático do aplicativo que consome os estilos. Para uma biblioteca de classes chamada ClassLib
e um aplicativo Blazor com uma folha de estilos BlazorSample.styles.css
, a folha de estilos da RCL é importada na parte superior da folha de estilos do aplicativo automaticamente no tempo de compilação:
@import '_content/ClassLib/ClassLib.bundle.scp.css';
Para os exemplos anteriores, a folha de estilos de Component1
(Component1.razor.css
) é agrupada automaticamente.
Component1.razor.css
na RCL de ComponentLibrary
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
A imagem em segundo plano também está incluída no modelo de projeto RCL e fica na pasta wwwroot
da RCL.
wwwroot/background.png
na RCL de ComponentLibrary
:
A imagem em segundo plano e a folha de estilos a seguir são usadas pelo componente de exemplo Component1
da RCL. Não é necessário adicionar esses ativos estáticos a uma nova RCL criada a partir do modelo de projeto RCL, pois eles são adicionados automaticamente pelo modelo de projeto.
wwwroot/background.png
na RCL de ComponentLibrary
:
wwwroot/styles.css
na RCL de ComponentLibrary
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
Para fornecer a classe CSS my-component
de Component1
, vincule-se à folha de estilos da biblioteca na marcação <head>
do aplicativo (local do <head>
conteúdo):
<link href="_content/ComponentLibrary/styles.css" rel="stylesheet" />
Disponibilizar componentes roteáveis na RCL
Para disponibilizar componentes roteáveis na RCL para solicitações diretas, o assembly da RCL deve ser divulgado para o roteador do aplicativo.
Abra o componente do aplicativo App
(App.razor
). Atribua uma coleção Assembly ao parâmetro AdditionalAssemblies do componente Router para incluir o assembly da RCL. No exemplo a seguir, o componente ComponentLibrary.Component1
é usado para descobrir o assembly da RCL.
AdditionalAssemblies="new[] { typeof(ComponentLibrary.Component1).Assembly }"
Para obter mais informações, confira Roteamento e navegação do Blazor no ASP.NET Core.
Criação de uma RCL com ativos estáticos na pasta wwwroot
Os ativos estáticos de uma RCL estão disponíveis para qualquer aplicativo que consuma a biblioteca.
Coloque ativos estáticos na pasta wwwroot
da RCL e faça referência aos ativos estáticos com o seguinte caminho no aplicativo: _content/{PACKAGE ID}/{PATH AND FILE NAME}
. O espaço reservado {PACKAGE ID}
é a ID do pacote da biblioteca. A ID do pacote terá como valor padrão o nome do assembly do projeto, se <PackageId>
não for especificado no arquivo de projeto. O espaço reservado {PATH AND FILE NAME}
é o caminho e o nome do arquivo em wwwroot
. O formato de caminho também é usado no aplicativo para ativos estáticos fornecidos por um pacote NuGet adicionado à RCL.
O exemplo a seguir mostra o uso de ativos estáticos de RCL com uma RCL chamada ComponentLibrary
e um aplicativo Blazor que consome a RCL. O aplicativo tem uma referência de projeto para a RCL ComponentLibrary
.
A imagem do Jeep a® seguir é usada no exemplo desta seção. Se você implementar o exemplo mostrado nesta seção, clique com o botão direito do mouse na imagem para salvá-la localmente.
wwwroot/jeep-yj.png
na RCL de ComponentLibrary
:
Adicione o componente JeepYJ
a seguir à RCL.
JeepYJ.razor
na RCL de ComponentLibrary
:
<h3>ComponentLibrary.JeepYJ</h3>
<p>
<img alt="Jeep YJ®" src="_content/ComponentLibrary/jeep-yj.png" />
</p>
Adicione o componente Jeep
a seguir ao aplicativo que consome a RCL ComponentLibrary
. O componente Jeep
usa:
- A imagem do Jeep YJ® da pasta
ComponentLibrary
da RCLwwwroot
. - O componente
JeepYJ
da RCL.
Jeep.razor
:
@page "/jeep"
@using ComponentLibrary
<div style="float:left;margin-right:10px">
<h3>Direct use</h3>
<p>
<img alt="Jeep YJ®" src="_content/ComponentLibrary/jeep-yj.png" />
</p>
</div>
<JeepYJ />
<p>
<em>Jeep</em> and <em>Jeep YJ</em> are registered trademarks of
<a href="https://www.stellantis.com">FCA US LLC (Stellantis NV)</a>.
</p>
Componente Jeep
renderizado:
Para obter mais informações, consulte Interface do usuário reutilizávelRazor em bibliotecas de classes com ASP.NET Core.
Criação de uma RCL com arquivos JavaScript colocados com componentes
A colocação de arquivos JavaScript (JS) para componentes Razor é uma maneira conveniente de organizar scripts em um aplicativo.
Os componentes Razor de aplicativos Blazor colocam arquivos JS usando a extensão .razor.js
e são endereçáveis publicamente usando o caminho para o arquivo no projeto:
{PATH}/{COMPONENT}.razor.js
- O espaço reservado
{PATH}
é o caminho para o componente. - O espaço reservado
{COMPONENT}
é o componente.
Quando o aplicativo é publicado, a estrutura move automaticamente o script para a raiz da Web. Os scripts são movidos para bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js
, onde estão os espaços reservados:
{TARGET FRAMEWORK MONIKER}
é o Moniker da Estrutura de Destino (TFM).{PATH}
é o caminho para o componente.{COMPONENT}
é o nome do componente.
Nenhuma alteração é necessária para a URL relativa do script, pois Blazor cuida de colocar o arquivo JS em ativos estáticos publicados para você.
Esta seção e os exemplos a seguir se concentram principalmente em explicar a colocação de arquivos JS. O primeiro exemplo demonstra um arquivo colocado JS com uma função comum JS. O segundo exemplo demonstra a utilização de um módulo para carregar uma função, que é a abordagem recomendada para a maioria dos aplicativos de produção. Chamar JS a partir do .NET é totalmente abordado em Chamar funções JavaScript de métodos .NET no ASP.NET Core Blazor, em que há mais explicações sobre a API BlazorJS com exemplos adicionais. O descarte de componentes, que está presente no segundo exemplo, é abordado em Ciclo de vida do componente ASP.NET CoreRazor.
O componente JsCollocation1
a seguir carrega um script por meio de um componente HeadContent
e chama uma função JS com IJSRuntime.InvokeAsync. O espaço reservado {PATH}
é o caminho para o componente.
Importante
Se você usar o seguinte código para uma demonstração em um aplicativo de teste, altere o espaço reservado {PATH}
para o caminho do componente (por exemplo: Components/Pages
em .NET 8 ou posterior ou Pages
em .NET 7 ou anterior). Em um Blazor Web App (.NET 8 ou mais recente), o componente requer um modo de renderização interativo aplicado ou globalmente ao aplicativo ou à definição do componente.
Adicione o script a seguir após o script Blazor (local do script inicial Blazor):
<script src="{PATH}/JsCollocation1.razor.js"></script>
Componente JsCollocation1
({PATH}/JsCollocation1.razor
):
@page "/js-collocation-1"
@inject IJSRuntime JS
<PageTitle>JS Collocation 1</PageTitle>
<h1>JS Collocation Example 1</h1>
<button @onclick="ShowPrompt">Call showPrompt1</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private string? result;
public async void ShowPrompt()
{
result = await JS.InvokeAsync<string>(
"showPrompt1", "What's your name?");
StateHasChanged();
}
}
O arquivo colocado JS é colocado ao lado do arquivo de componente JsCollocation1
com o nome do arquivo JsCollocation1.razor.js
. No componente JsCollocation1
, o script é referenciado no caminho do arquivo colocado. No exemplo a seguir, a função showPrompt1
aceita o nome do usuário de um Window prompt()
e o retorna ao componente JsCollocation1
para exibição.
{PATH}/JsCollocation1.razor.js
:
function showPrompt1(message) {
return prompt(message, 'Type your name here');
}
A abordagem anterior não é recomendada para uso geral em aplicativos de produção porque polui o cliente com funções globais. Uma abordagem melhor para aplicativos de produção é usar módulos JS. Os mesmos princípios gerais se aplicam ao carregamento de um módulo JS de um arquivo JS colocado, como o próximo exemplo demonstra.
O método OnAfterRenderAsync
do componente JsCollocation2
a seguir carrega um módulo JS em module
, que é uma classe de componente IJSObjectReference. module
é usado para chamar a função showPrompt2
. O espaço reservado {PATH}
é o caminho para o componente.
Importante
Se você usar o seguinte código para uma demonstração em um aplicativo de teste, altere o espaço reservado {PATH}
para o caminho do componente. Em um Blazor Web App (.NET 8 ou mais recente), o componente requer um modo de renderização interativo aplicado ou globalmente ao aplicativo ou à definição do componente.
Componente JsCollocation2
({PATH}/JsCollocation2.razor
):
@page "/js-collocation-2"
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>JS Collocation 2</PageTitle>
<h1>JS Collocation Example 2</h1>
<button @onclick="ShowPrompt">Call showPrompt2</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private IJSObjectReference? module;
private string? result;
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
/*
Change the {PATH} placeholder in the next line to the path of
the collocated JS file in the app. Examples:
./Components/Pages/JsCollocation2.razor.js (.NET 8 or later)
./Pages/JsCollocation2.razor.js (.NET 7 or earlier)
*/
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./{PATH}/JsCollocation2.razor.js");
}
}
public async void ShowPrompt()
{
if (module is not null)
{
result = await module.InvokeAsync<string>(
"showPrompt2", "What's your name?");
StateHasChanged();
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
{PATH}/JsCollocation2.razor.js
:
export function showPrompt2(message) {
return prompt(message, 'Type your name here');
}
O uso de scripts e módulos para JS agrupados em uma biblioteca de classes de Razor (RCL) só tem suporte para JSmecanismo de interoperabilidade de Blazor com base na interface IJSRuntime. Se você estiver implementando a interop [JSImport]
/[JSExport]
JavaScript, consulte Interop JSImport/JSExport JavaScript com o ASP.NET Core Blazor.
Para scripts ou módulos fornecidos por uma biblioteca de classes (RCL) Razor, usando interop JS baseada emIJSRuntime, o seguinte caminho é usado:
./_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js
- O segmento de linha para o diretório atual (
./
) é necessário para criar o caminho de ativo estático correto para o arquivo JS. - O espaço reservado
{PACKAGE ID}
é o identificador do pacote da RCL (ou nome da biblioteca para uma biblioteca de classes referenciada pelo aplicativo). - O espaço reservado
{PATH}
é o caminho para o componente. Se um componente Razor estiver localizado na raiz da RCL, o segmento de linha não será incluído. - O espaço reservado
{COMPONENT}
é o nome do componente. - O espaço reservado
{EXTENSION}
corresponde à extensão do componenterazor
oucshtml
.
No seguinte exemplo de aplicativo Blazor:
- O identificador do pacote da RCL é
AppJS
. - Os scripts de um módulo são carregados para o componente
JsCollocation3
(JsCollocation3.razor
). - O componente
JsCollocation3
está na pastaComponents/Pages
da RCL.
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./_content/AppJS/Components/Pages/JsCollocation3.razor.js");
Fornecer componentes e ativos estáticos para vários aplicativos Blazor hospedados
Para obter mais informações, confira Vários aplicativos Blazor WebAssembly do ASP.NET Core hospedados.
Analisador de compatibilidade de navegador do lado do cliente
Os aplicativos do lado do cliente têm como destino a área de superfície completa da API do .NET, mas nem todas as APIs do .NET têm suporte no WebAssembly devido a restrições de área restrita do navegador. APIs sem suporte geram PlatformNotSupportedException durante a execução no WebAssembly. Um analisador de compatibilidade de plataforma avisa o desenvolvedor quando o aplicativo usa APIs que não têm suporte nas plataformas de destino do aplicativo. Para aplicativos do lado do cliente, isso significa verificar se há suporte para APIs em navegadores. Os APIs da estrutura .NET para o analisador de compatibilidade é um processo em andamento, portanto, nem todas as APIs do .NET Framework estão anotadas no momento.
Blazor Web Apps que habilitam componentes webAssembly interativos, aplicativos Blazor WebAssembly e projetos RCL habilitam automaticamente as verificações de compatibilidade do navegador adicionando browser
como uma plataforma compatível com o item MSBuild SupportedPlatform
. Os desenvolvedores de biblioteca podem adicionar manualmente o item SupportedPlatform
ao arquivo de projeto de uma biblioteca para habilitar o recurso:
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
Ao criar uma biblioteca, indique que uma API específica não tem suporte em navegadores especificando browser
para UnsupportedOSPlatformAttribute:
using System.Runtime.Versioning;
...
[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{
...
}
Para obter mais informações, confira Anotar APIs como sem suporte em plataformas específicas (repositório do GitHub dotnet/designs
.
Isolamento de JavaScript em módulos JavaScript
Blazor habilita o isolamento de JavaScript em módulos JavaScript padrão. O isolamento de JavaScript oferece os seguintes benefícios:
- O JavaScript importado não polui mais o namespace global.
- Os consumidores de uma biblioteca e componentes não precisam importar o JavaScript relacionado.
Para obter mais informações, consulte Chamar funções JavaScript de métodos .NET no ASP.NET Core Blazor.
Evite cortar os métodos do .NET que podem ser invocados por JavaScript
A nova vinculação de runtime corta os métodos do .NET que podem ser invocados pelo JavaScript da instância de classe, a menos que estejam explicitamente protegidos. Para obter mais informações, confira Chamar métodos do .NET das funções JavaScript no Blazor do ASP.NET Core.
Compilar, empacotar e enviar para o NuGet
Como as bibliotecas de classes Razor que contêm componentes Razor são bibliotecas .NET padrão, o empacotamento e envio para o NuGet não é diferente de empacotamento e envio de qualquer biblioteca para o NuGet. O empacotamento é executado usando o comando dotnet pack
em um shell de comando:
dotnet pack
Carregue o pacote no NuGet usando o comando dotnet nuget push
em um shell de comando.
Marcas comerciais
Jeep e Jeep YJ são marcas registradas da FCA US LLC (Stellantis NV).
Recursos adicionais
- Interface do usuário do Razor reutilizável em bibliotecas de classes com o ASP.NET Core
- Usar APIs do ASP.NET Core em uma biblioteca de classes
- Adicionar um arquivo de configuração do Filtro de Linguagem Intermediária XML (IL) a uma biblioteca
- Suporte ao isolamento de CSS com bibliotecas de classes Razor