Partager via


Partagez des ressources entre des clients web et natifs à l’aide d’une bibliothèque de classes (RCL) Razor

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 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 prise en charge de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 8 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 8 de cet article.

Utilisez une bibliothèque de classes (RCL) Razor pour partager des composants Razor, du code C# et des ressources statiques entre des projets clients web et natifs.

Cet article s’appuie sur les concepts généraux trouvés dans les articles suivants :

Les exemples de cet article partagent des ressources entre une application Blazor côté serveur et une application .NET MAUIBlazor Hybrid dans la même solution :

  • Bien qu’une application Blazor côté serveur soit utilisée, les directives s’appliquent également aux applications Blazor WebAssembly qui partagent des ressources avec une application Blazor Hybrid.
  • Les projets se trouvent dans la même solution, mais une RCL peut fournir des ressources partagées aux projets en dehors d’une solution.
  • La RCL est ajoutée en tant que projet à la solution, mais n’importe quelle RCL peut être publiée en tant que package NuGet. Un package NuGet peut fournir des ressources partagées à des projets clients natifs et web.
  • L’ordre de création des projets n’est pas important. Toutefois, les projets qui s’appuient sur une RCL pour les ressources doivent créer une référence de projet à la RCL après la création de la LRC.

Pour obtenir des conseils sur la création d’une RCL, consultez Utiliser des composants Razor ASP.NET Core à partir Razor d’une bibliothèque de classes (RCL). Si vous le souhaitez, accédez aux conseils supplémentaires sur les RCL qui s’appliquent largement aux applications ASP.NET Core dans l’interface utilisateur Razor réutilisable dans les bibliothèques de classes avec ASP.NET Core.

Infrastructures cibles pour les déploiements ClickOnce

Pour publier un projet WPF ou Windows Forms avec une bibliothèque de classes (RCL) Razor dans .NET 6 avec ClickOnce, la RCL doit cibler net6.0-windows en plus de net6.0.

Exemple :

<TargetFrameworks>net6.0;net6.0-windows</TargetFrameworks>

Pour plus d’informations, consultez les articles suivants :

Partagez des composants d’interface utilisateur web Razor, du code et des ressources statiques

Les composants d’une RCL peuvent être partagés simultanément par des applications clientes web et natives créées à l’aide de Blazor. Les instructions fournies dans Utiliser des composants ASP.NET Core Razor à partir d’une bibliothèque de classes (RCL) Razor expliquent comment partager des composants Razor à l’aide d’une bibliothèque de classes (RCL) Razor. Les mêmes instructions s’appliquent à la réutilisation des composants Razor d’une RCL dans une application Blazor Hybrid.

Les espaces de noms des composants sont dérivés de l’ID du package ou du nom de l’assembly de la RCL et du chemin d’accès au dossier du composant dans la RCL. Pour plus d’informations, consultez Composants ASP.NET Core Razor. Les directives @using peuvent être placées dans des fichiers _Imports.razor pour les composants et le code, comme le montre l’exemple suivant pour une RCL nommée SharedLibrary avec un dossier Shared de composants Razor partagés et un dossier Data de classes de données partagées :

@using SharedLibrary
@using SharedLibrary.Shared
@using SharedLibrary.Data

Placez les ressources statiques partagées dans le dossier wwwroot de la RCL et mettez à jour les chemins d’accès aux ressources statiques dans l’application pour utiliser le format de chemin d’accès suivant :

_content/{PACKAGE ID/ASSEMBLY NAME}/{PATH}/{FILE NAME}

Espaces réservés :

  • {PACKAGE ID/ASSEMBLY NAME} : l’ID de package ou nom d’assembly de la RCL.
  • {PATH} : le chemin d’accès facultatif dans le dossier wwwroot de la RCL.
  • {FILE NAME} : le nom de fichier de la ressource statique.

Le format de chemin d’accès précédent est également utilisé dans l’application pour les ressources statiques fournies par un package NuGet ajouté à la RCL.

Pour une RCL nommée SharedLibrary et utilisant la feuille de style de démarrage minifiée comme exemple :

_content/SharedLibrary/css/bootstrap/bootstrap.min.css

Pour plus d’informations sur la façon de partager des ressources statiques entre des projets, consultez les articles suivants :

Le fichier racine index.html est généralement spécifique à l’application et doit rester dans l’application Blazor Hybrid ou l’application Blazor WebAssembly. Le fichier index.html n’est généralement pas partagé.

Le composant racine Razor (App.razor ou Main.razor) peut être partagé, mais peut souvent avoir besoin d’être spécifique à l’application d’hébergement. Par exemple, App.razor est différent dans les modèles de projet Blazor WebAssembly et Blazor côté serveur lorsque l’authentification est activée. Vous pouvez ajouter le AdditionalAssembliesparamètre pour spécifier l’emplacement de tous les composants routables partagés, et vous pouvez spécifier un composant de disposition par défaut partagé pour le routeur par nom de type.

Fournissez du code et des services indépendamment du modèle d’hébergement

Lorsque le code doit différer selon les modèles d’hébergement ou les plateformes cibles, abstrayez le code en tant qu’interfaces et injectez les implémentations de service dans chaque projet.

L’exemple de données météorologiques suivant présente différentes implémentations de services de prévisions météorologiques :

  • Utilisation d’une requête HTTP pour Blazor Hybrid et Blazor WebAssembly.
  • Requête de données directement pour une application Blazor côté serveur.

L’exemple utilise les spécifications et conventions suivantes :

  • La RCL est nommée SharedLibrary et contient les dossiers et espaces de noms suivants :
    • Data : contient la classe WeatherForecast, qui sert de modèle pour les données météorologiques.
    • Interfaces : contient l’interface de service pour les implémentations de service, nommée IWeatherForecastService.
  • Le composant FetchData est conservé dans le dossier Pages de la RCL, qui est routable par toutes les applications qui consomment la RCL.
  • Chaque application Blazor gère une implémentation de service qui implémente l’interface IWeatherForecastService.

Data/WeatherForecast.cs dans la 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 dans la RCL :

using SharedLibrary.Data;

namespace SharedLibrary.Interfaces;

public interface IWeatherForecastService
{
    Task<WeatherForecast[]?> GetForecastAsync(DateTime startDate);
}

Le fichier _Imports.razor dans la RCL inclut les espaces de noms ajoutés suivants :

@using SharedLibrary.Data
@using SharedLibrary.Interfaces

Services/WeatherForecastService.cs dans les applications Blazor Hybrid et 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");
}

Dans l’exemple précédent, l’espace réservé {APP NAMESPACE} est l’espace de noms de l’application.

Services/WeatherForecastService.cs dans l’application Blazor côté serveur :

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());
}

Dans l’exemple précédent, l’espace réservé {APP NAMESPACE} est l’espace de noms de l’application.

Les applications Blazor Hybrid, Blazor WebAssembly et Blazor côté serveur inscrivent leurs implémentations de service de prévision météorologique (Services.WeatherForecastService) pour IWeatherForecastService.

Le projet Blazor WebAssembly inscrit également un HttpClient. Le HttpClient inscrit par défaut dans une application créée à partir du modèle de projet Blazor WebAssembly est suffisant à cet effet. Pour plus d’informations, consultez Appeler une API web à partir d’une application Blazor ASP.NET Core.

Pages/FetchData.razor dans la 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);
    }
}

Ressources supplémentaires