Consommer des composants ASP.NET Core Razor à partir d'une bibliothèque de classes Razor (RCL)
Remarque
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 9 de cet article.
Avertissement
Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 9 de cet article.
Important
Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.
Pour la version actuelle, consultez la version .NET 9 de cet article.
Les composants peuvent être partagés dans une bibliothèque de classes Razor (RCL) entre les projets. Incluez des composants et des ressources statiques dans une application à partir de :
- Un autre projet dans la solution.
- Bibliothèque .NET référencée.
- Un package NuGet.
Tout comme les composants sont des types .NET standard, les composants fournis par un RCL sont des assemblys .NET normaux.
Créer une RCL
- Créer un nouveau projet.
- Dans la boîte de dialogue Créer un projet, sélectionnez Bibliothèque de classes Razor dans la liste des modèles de projet ASP.NET Core. Cliquez sur Suivant.
- Dans la boîte de dialogue Configurer votre nouveau projet, indiquez un nom de projet dans le champ Nom du projet. Les exemples de cette rubrique utilisent le nom de projet
ComponentLibrary
. Cliquez sur Suivant. - Dans la boîte de dialogue Informations supplémentaires, ne sélectionnez pas l’option Prendre en charge les pages et les vues. Sélectionnez Créer.
- Ajoutez la RCL à une solution :
- Ouvrez la solution.
- Cliquez avec le bouton droit sur la solution dans l’Explorateur de solutions. Sélectionnez Ajouter>un projet existant.
- Accédez au fichier projet de la RCL.
- Sélectionnez le fichier projet de la RCL (
.csproj
).
- Ajoutez une référence à la RCL à partir de l’application :
- Faites un clic droit sur le projet d’application. Sélectionnez Ajouter>Référence de projet.
- Sélectionnez le projet RCL. Cliquez sur OK.
Consommer un composant Razor à partir d’une bibliothèque RCL
Pour utiliser des composants d’une RCL dans un autre projet, utilisez l’une des approches suivantes :
- Utilisez le nom de type de composant complet, qui inclut l’espace de noms de la RCL.
- Des composants individuels peuvent être ajoutés par nom sans l’espace de noms de la RCL si la directive
@using
de Razor déclare l’espace de noms de la RCL. Utilisez les approches suivantes :- Ajoutez la directive
@using
à des composants individuels. - Incluez la directive
@using
dans le fichier_Imports.razor
de niveau supérieur pour rendre les composants de la bibliothèque accessibles à l’ensemble d’un projet. Ajoutez la directive à un fichier_Imports.razor
à n’importe quel niveau pour appliquer l’espace de noms à un composant unique ou à un ensemble de composants au sein d’un dossier. Lorsqu’un fichier_Imports.razor
est utilisé, les composants individuels ne nécessitent pas de directive@using
pour l’espace de noms de la RCL.
- Ajoutez la directive
Dans les exemples suivants, ComponentLibrary
est une RCL contenant le composant Component1
. Le composant Component1
est un exemple de composant automatiquement ajouté à une RCL créée à partir du modèle de projet RCL qui n’est pas créé pour prendre en charge les pages et les vues.
Component1.razor
dans la RCL ComponentLibrary
:
<div class="my-component">
This component is defined in the <strong>ComponentLibrary</strong> package.
</div>
Dans l’application qui consomme la RCL, référencez le composant Component1
à l’aide de son espace de noms, comme l’illustre l’exemple suivant.
ConsumeComponent1.razor
:
@page "/consume-component-1"
<h1>Consume component (full namespace example)</h1>
<ComponentLibrary.Component1 />
Vous pouvez également ajouter une directive @using
et utiliser le composant sans son espace de noms. La directive @using
suivante peut également apparaître dans n’importe quel fichier _Imports.razor
dans ou au-dessus du dossier actif.
ConsumeComponent2.razor
:
@page "/consume-component-2"
@using ComponentLibrary
<h1>Consume component (<code>@@using</code> example)</h1>
<Component1 />
Pour les composants de bibliothèque qui utilisent l’isolation du CSS, les styles de composant sont automatiquement mis à la disposition de l’application consommatrice. Il n’est pas nécessaire de lier ou d’importer manuellement les feuilles de style des composants individuels de la bibliothèque ou son fichier CSS groupé dans l’application qui consomme la bibliothèque. L’application utilise des importations CSS pour référencer les styles groupés de la RCL. Les styles groupés ne sont pas publiés en tant que ressource web statique de l’application qui consomme la bibliothèque. Pour une bibliothèque de classes nommée ClassLib
et une application Blazor avec une feuille de style BlazorSample.styles.css
, la feuille de style RCL est importée en haut de la feuille de style de l’application automatiquement au moment de la génération :
@import '_content/ClassLib/ClassLib.bundle.scp.css';
Pour les exemples précédents, la feuille de style de Component1
(Component1.razor.css
) est groupée automatiquement.
Component1.razor.css
dans la RCL ComponentLibrary
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
L’image d’arrière-plan est également incluse à partir du modèle de projet RCL et réside dans le dossier wwwroot
de la RCL.
wwwroot/background.png
dans la RCL ComponentLibrary
:
Pour fournir des styles de composants de bibliothèque supplémentaires à partir de feuilles de style dans le dossier wwwroot
de la bibliothèque, ajoutez des balises <link>
de feuille de style au consommateur de la RCL, comme le montre l’exemple suivant.
Important
En règle générale, les composants de bibliothèque utilisent l’isolation CSS pour regrouper et fournir des styles de composants. Les styles de composants qui reposent sur l’isolation CSS sont automatiquement mis à la disposition de l’application qui utilise la RCL. Il n’est pas nécessaire de lier ou d’importer manuellement les feuilles de style des composants individuels de la bibliothèque ou son fichier CSS groupé dans l’application qui consomme la bibliothèque. L’exemple suivant permet de fournir des feuilles de style globales en dehors de l’isolation CSS, ce qui n’est généralement pas une exigence pour les applications classiques qui consomment des RCL.
L’image d’arrière-plan suivante est utilisée dans le prochain exemple. Si vous implémentez l’exemple présenté dans cette section, cliquez avec le bouton droit sur l’image pour l’enregistrer localement.
wwwroot/extra-background.png
dans la RCL ComponentLibrary
:
Ajoutez une nouvelle feuille de style à la RCL avec une classe extra-style
.
wwwroot/additionalStyles.css
dans la RCL ComponentLibrary
:
.extra-style {
border: 2px dashed blue;
padding: 1em;
margin: 1em 0;
background-image: url('extra-background.png');
}
Ajoutez un composant à la RCL qui utilise la classe extra-style
.
ExtraStyles.razor
dans la RCL ComponentLibrary
:
<div class="extra-style">
<p>
This component is defined in the <strong>ComponentLibrary</strong> package.
</p>
</div>
Ajoutez une page à l’application qui utilise le composant ExtraStyles
de la RCL.
ConsumeComponent3.razor
:
@page "/consume-component-3"
@using ComponentLibrary
<h1>Consume component (<code>additionalStyles.css</code> example)</h1>
<ExtraStyles />
Lien vers la feuille de style de la bibliothèque dans le balisage <head>
de l’application (emplacement du contenu <head>
) :
Blazor Web App :
<link href="@Assets["_content/ComponentLibrary/additionalStyles.css"]" rel="stylesheet">
Applications Blazor WebAssembly autonomes :
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
Pour les composants de bibliothèque qui utilisent l’isolation du CSS, les styles de composant sont automatiquement mis à la disposition de l’application consommatrice. Il n’est pas nécessaire de lier ou d’importer manuellement les feuilles de style des composants individuels de la bibliothèque ou son fichier CSS groupé dans l’application qui consomme la bibliothèque. L’application utilise des importations CSS pour référencer les styles groupés de la RCL. Les styles groupés ne sont pas publiés en tant que ressource web statique de l’application qui consomme la bibliothèque. Pour une bibliothèque de classes nommée ClassLib
et une application Blazor avec une feuille de style BlazorSample.styles.css
, la feuille de style RCL est importée en haut de la feuille de style de l’application automatiquement au moment de la génération :
@import '_content/ClassLib/ClassLib.bundle.scp.css';
Pour les exemples précédents, la feuille de style de Component1
(Component1.razor.css
) est groupée automatiquement.
Component1.razor.css
dans la RCL ComponentLibrary
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
L’image d’arrière-plan est également incluse à partir du modèle de projet RCL et réside dans le dossier wwwroot
de la RCL.
wwwroot/background.png
dans la RCL ComponentLibrary
:
L’image d’arrière-plan et la feuille de style suivantes sont utilisées par l’exemple Component1
de composant RCL. Il n’est pas nécessaire d’ajouter ces ressources statiques à une nouvelle RCL créée à partir du modèle de projet RCL, car elles sont ajoutées automatiquement par le modèle de projet.
wwwroot/background.png
dans la RCL ComponentLibrary
:
wwwroot/styles.css
dans la RCL ComponentLibrary
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
Pour fournir la classe Component1
CSS de my-component
, créez un lien vers la feuille de style de la bibliothèque dans le balisage de l'application <head>
(localisation de contenu <head>
) :
<link href="_content/ComponentLibrary/styles.css" rel="stylesheet" />
Rendre les composants routables disponibles à partir de la Bibliothèque de classes (RCL)
Pour rendre des composants routables dans la RCL disponibles pour des requêtes directes, l’assembly de la RCL doit être divulgué au routeur de l’application.
Ouvrez le composant App
de l’application (App.razor
). Affectez une collection Assembly au paramètre AdditionalAssemblies du composant Router pour inclure l’assembly de la RCL. Dans l’exemple suivant, le composant ComponentLibrary.Component1
est utilisé pour découvrir l’assembly de la RCL.
AdditionalAssemblies="new[] { typeof(ComponentLibrary.Component1).Assembly }"
Pour plus d’informations, consultez Routage et navigation ASP.NET Core Blazor.
Créer une RCL avec des ressources statiques dans le dossier wwwroot
Les ressources statiques d’une RCL sont disponibles pour toute application qui consomme la bibliothèque.
Placez les ressources statiques dans le dossier wwwroot
de la RCL et référencez les ressources statiques avec le chemin d’accès suivant dans l’application : _content/{PACKAGE ID}/{PATH AND FILE NAME}
. L’espace réservé {PACKAGE ID}
est l’ID de package de la bibliothèque. L’ID de package est défini par défaut sur le nom d’assembly du projet si <PackageId>
n’est pas spécifié dans le fichier projet. L’espace réservé {PATH AND FILE NAME}
correspond au chemin d’accès et au nom de fichier sous wwwroot
. Ce format de chemin d’accès est également utilisé dans l’application pour les ressources statiques fournies par les packages NuGet ajoutés à la RCL.
L’exemple suivant illustre l’utilisation de ressources statiques de la RCL avec une RCL nommée ComponentLibrary
et une application Blazor qui utilise la RCL. L’application a une référence de projet pour la RCL ComponentLibrary
.
L’image Jeep® suivante est utilisée dans l’exemple de cette section. Si vous implémentez l’exemple présenté dans cette section, cliquez avec le bouton droit sur l’image pour l’enregistrer localement.
wwwroot/jeep-yj.png
dans la RCL ComponentLibrary
:
Ajoutez le composant JeepYJ
suivant à la RCL.
JeepYJ.razor
dans la RCL ComponentLibrary
:
<h3>ComponentLibrary.JeepYJ</h3>
<p>
<img alt="Jeep YJ®" src="_content/ComponentLibrary/jeep-yj.png" />
</p>
Ajoutez le composant Jeep
suivant à l’application qui consomme la RCL ComponentLibrary
. Le composant Jeep
utilise :
- L’image Jeep YJ® du dossier
wwwroot
de la RCLComponentLibrary
. - Composant
JeepYJ
de la 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>
Composant Jeep
rendu :
Pour plus d’informations, consultez Interface utilisateur Razor réutilisable dans les bibliothèques de classes avec ASP.NET Core.
Créer une RCL avec des fichiers JavaScript colocalisés avec des composants
La colocation de fichiers JavaScript (JS) pour les composants Razor constitue un moyen pratique pour organiser des scripts dans une application.
Les composants Razor pour les applications Blazor colocalisent des fichiers JS en utilisant l’extension .razor.js
et sont adressables publiquement en tirant parti du chemin d’accès au fichier dans le projet :
{PATH}/{COMPONENT}.razor.js
- L’espace réservé
{PATH}
constitue le chemin d’accès au composant. - L’espace réservé
{COMPONENT}
constitue le composant.
Quand l’application est publiée, l’infrastructure déplace automatiquement le script vers la racine web. Les scripts sont déplacés vers bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js
où les espaces réservés sont :
{TARGET FRAMEWORK MONIKER}
constitue le moniker de framework cible (TFM).{PATH}
constitue le chemin d’accès au composant.{COMPONENT}
constitue le nom de composant.
Aucune modification n’est requise pour l’URL relative du script, car Blazor se charge de placer le fichier JS dans des ressources statiques publiées à votre place.
Cette section et les exemples suivants sont principalement axés sur l’explication de la colocation de fichiers JS. Le premier exemple illustre un fichier colocalisé JS avec une fonction ordinaire JS. Le deuxième exemple illustre l’utilisation d’un module pour charger une fonction, ce qui correspond à l’approche recommandée pour la plupart des applications de production. L’appel JS à partir de .NET est entièrement couvert dans les fonctions JavaScript d’appel à partir de méthodes .NET dans ASP.NET CoreBlazor, où il existe d’autres explications de l’API BlazorJS avec des exemples supplémentaires. L’élimination des composants, qui est présente dans le deuxième exemple, est abordée dans Cycle de vie des composants Razor ASP.NET Core .
Le composant JsCollocation1
suivant charge un script via un composant HeadContent
et appelle une fonction JS avec IJSRuntime.InvokeAsync. L’espace réservé {PATH}
constitue le chemin d’accès au composant.
Important
Si vous utilisez le code suivant pour une démonstration dans une application de test, remplacez l’espace réservé {PATH}
par le chemin d’accès du composant (exemple : Components/Pages
dans .NET 8 ou ultérieur ou Pages
dans .NET 7 ou antérieur). Dans une Blazor Web App (.NET 8 ou version ultérieure), le composant nécessite un mode de rendu interactif appliqué globalement à l’application ou à la définition du composant.
Ajoutez le script suivant après le script Blazor (emplacement du script de démarrage Blazor) :
<script src="{PATH}/JsCollocation1.razor.js"></script>
Composant 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();
}
}
Le fichier colocalisé JS est placé en regard du fichier de composant JsCollocation1
avec le nom de fichier JsCollocation1.razor.js
. Dans le composant JsCollocation1
, le script est référencé au niveau du chemin du dossier colocalisé. Dans l’exemple suivant, la fonction showPrompt1
accepte le nom de l’utilisateur à partir d’un Window prompt()
et le retourne au composant JsCollocation1
pour l’affichage.
{PATH}/JsCollocation1.razor.js
:
function showPrompt1(message) {
return prompt(message, 'Type your name here');
}
L’approche précédente n’est pas recommandée pour une utilisation générale dans des applications de production, car elle pollue le client avec des fonctions globales. Une meilleure approche pour les applications de production consiste à utiliser des modules JS. Ces mêmes principes généraux s’appliquent au chargement d’un module JS à partir d’un fichier JS colocalisé, tel qu’illustré dans l’exemple suivant.
La méthode OnAfterRenderAsync
du composant JsCollocation2
suivant charge un module JS dans module
qui est un IJSObjectReference de la classe de composant. module
est utilisé pour appeler la fonction showPrompt2
. L’espace réservé {PATH}
constitue le chemin d’accès au composant.
Important
Si vous utilisez le code suivant pour une démonstration dans une application de test, remplacez l’espace réservé {PATH}
par le chemin d’accès du composant. Dans une Blazor Web App (.NET 8 ou version ultérieure), le composant nécessite un mode de rendu interactif appliqué globalement à l’application ou à la définition du composant.
Composant 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');
}
L’utilisation de scripts et de modules pour le JS colocalisé dans une bibliothèque de classes Razor (RCL) n’est prise en charge que pour le mécanisme d’interop JS de Blazor basé sur l’interface IJSRuntime. Si vous implémentez l’interopéabilité JavaScript [JSImport]
/[JSExport]
, consultez Interopérabilité JSImport/JSExport JavaScript avec ASP.NET Core Blazor.
Pour les scripts ou modules fournis par une bibliothèque de classes Razor (RCL) qui utilise l’interop JS basée sur IJSRuntime, le chemin d’accès suivant est utilisé :
./_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js
- Le segment de chemin pour le répertoire actuel (
./
) est requis pour créer le chemin de ressource statique correct vers le fichier JS. - L’espace réservé
{PACKAGE ID}
est l’identificateur de package de la bibliothèque RCL (ou le nom de la bibliothèque pour une bibliothèque de classes référencée par l’application). - L’espace réservé
{PATH}
constitue le chemin d’accès au composant. Si un composant Razor se trouve à la racine de la bibliothèque RCL, le segment de chemin n’est pas inclus. - L’espace réservé
{COMPONENT}
constitue le nom de composant. - L’espace réservé
{EXTENSION}
correspond à l’extension du composant,razor
oucshtml
.
Dans l’exemple d’application Blazor suivant :
- L’identificateur de package de la bibliothèque RCL est
AppJS
. - Les scripts d’un module sont chargés pour le composant
JsCollocation3
(JsCollocation3.razor
). - Le composant
JsCollocation3
figure dans le dossierComponents/Pages
de la bibliothèque RCL.
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./_content/AppJS/Components/Pages/JsCollocation3.razor.js");
Fournir des composants et des ressources statiques à plusieurs applications Blazor hébergées
Pour plus d’informations, consultez Plusieurs applications ASP.NET Core Blazor WebAssembly hébergées.
Analyseur de compatibilité du navigateur côté client
Les applications côté client ciblent toute la surface de l’API .NET, mais toutes les API .NET ne sont pas prises en charge sur WebAssembly en raison des contraintes du bac à sable du navigateur. Les API non prises en charge lèvent PlatformNotSupportedException lors de leur exécution sur WebAssembly. Un analyseur de compatibilité de plateforme avertit le développeur quand l’application utilise des API qui ne sont pas prises en charge par les plateformes cibles de l’application. Pour les applications côté client, cela signifie vérifier que les API sont prises en charge dans les navigateurs. L’annotation des API .NET Framework pour l’analyseur de compatibilité est un processus constant. Par conséquent, toutes les API du framework .NET ne sont pas actuellement annotées.
Les Blazor Web App qui activent des composants WebAssembly interactifs, les applications Blazor WebAssembly et les projets RCL activent automatiquement les vérifications de compatibilité du navigateur en ajoutant browser
en tant que plateforme prise en charge avec l’élément MSBuild SupportedPlatform
. Les développeurs de bibliothèques peuvent ajouter manuellement l’élément SupportedPlatform
au fichier projet d’une bibliothèque pour activer la fonctionnalité :
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
Lors de la création d’une bibliothèque, indiquez qu’une API particulière n’est pas prise en charge dans les navigateurs en spécifiant browser
sur UnsupportedOSPlatformAttribute :
using System.Runtime.Versioning;
...
[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{
...
}
Pour plus d’informations, consultez Annoter les API comme non prises en charge sur des plateformes spécifiques (dépôt GitHub dotnet/designs
.
Isolation JavaScript dans les modules JavaScript
Blazor active l’isolation JavaScript dans les modules JavaScript standard. L’isolation JavaScript offre les avantages suivants :
- Le code JavaScript importé ne pollue plus l’espace de noms global.
- Les consommateurs d’une bibliothèque et de composants ne sont pas tenus d’importer le code JavaScript associé manuellement.
Pour plus d’informations, consultez Appeler des fonctions JavaScript à partir de méthodes .NET dans ASP.NET Core Blazor.
Évitez de découper les méthodes .NET disponibles pour JavaScript
La nouvelle liaison du runtime supprime les méthodes .NET disponibles pour JavaScript de l’instance de classe, sauf si elles sont explicitement conservées. Pour plus d’informations, consultez Appeler des fonctions JavaScript à partir de méthodes .NET dans ASP.NET Core Blazor.
Générer, empaqueter et expédier à NuGet
Étant donné que les bibliothèques de classes Razor qui contiennent des composants Razor sont des bibliothèques .NET standard, leur empaquetage et leur expédition à NuGet ne sont pas différents de l’empaquetage et de l’expédition d’une bibliothèque à NuGet. L’empaquetage est effectué à l’aide de la commande dotnet pack
dans un interpréteur de commandes :
dotnet pack
Chargez le package dans NuGet à l’aide de la commande dotnet nuget push
dans un interpréteur de commandes.
Marques déposées
Jeep et Jeep YJ sont des marques déposées de FCA US LLC (Stellantis NV).
Ressources supplémentaires
- Interface utilisateur Razor réutilisable dans les bibliothèques de classes avec ASP.NET Core
- Utiliser les API ASP.NET Core dans une bibliothèque de classes
- Ajouter un fichier de configuration de découpage en langage intermédiaire (IL) XML à une bibliothèque
- Prise en charge de l’isolation CSS avec les bibliothèques de classes Razor