Fermer

décembre 16, 2022

Implémentations de Blazor sur le Web et natif

Implémentations de Blazor sur le Web et natif


Blazor peut piloter l’interface utilisateur/UX sur les plates-formes Web et natives, mais les implémentations peuvent varier.

Blazor mange le monde. Les développeurs .NET ont naturellement été enthousiasmés par Blazor, un framework Web moderne permettant le code C # avant et arrière. Blazor peut s’exécuter côté serveur ou entièrement côté client avec WebAssembly, et le modèle de composant/rendu Blazor inspire confiance avec stabilité et extensibilité.

Avec .NET Multi-platform App UI (.NET MAUI), Blazor goodness ne se limite pas aux seules applications Web, mais est désormais très bienvenu sur les applications multiplateformes natives pour mobile et ordinateur de bureau. Même si les composants/styles Blazor peuvent rendre la même interface utilisateur (UI) sur le Web, le bureau et le mobile, l’expérience utilisateur (UX) ne devrait pas être la même. En fait, les développeurs voudront avoir la flexibilité de faire différentes choses avec Blazor sur différentes plates-formes. Explorons comment une seule base de code partagée permet au code Blazor d’avoir différentes implémentations sur toutes les plates-formes – le partage entre les différences est attentionné.

PS : Cet article fait partie de la Calendrier de l’Avent C#, dirigé par Matthew Groves et Calvin Allen. Connectez-vous tous les jours pour découvrir du contenu .NET/C# exceptionnel jusqu’à Noël !

Blazor avec .NET MAUI

Blazor est le framework Web gratuit, open-source et très apprécié pour la création d’applications Web modernes. Les développeurs qui souhaitent rester à l’écart de JavaScript peuvent tirer parti de la puissance de .NET, C# et des outils modernes pour créer de belles applications Web interactives. Le modèle de composant Blazor, le moteur de rendu et les mécanismes de style offrent de la flexibilité : les applications Blazor peuvent s’exécuter côté serveur dans ASP.NET Core ou entièrement côté client avec WebAssembly.

.NET FIXE est l’évolution de la stratégie multiplateforme .NET, un nouveau cadre pour la création d’applications mobiles et de bureau natives avec C#/XAML. Cependant, .NET MAUI apporte quelque chose de magique appelé le composant BlazorWebView – une abstraction qui trouve les navigateurs permanents sur les plates-formes respectives et permet le rendu des artefacts Web dans le shell des applications natives.

Blazor et .NET MAUI sont presque faits l’un pour l’autre, partageant le runtime .NET exact – .NET 6 hier et .NET 7 aujourd’hui. Les applications Blazor peuvent désormais être facilement hébergées dans les applications .NET MAUI, avec une intégration complète de la plate-forme native. Les applications Blazor Hybrid, comme on les appelle, permettent de nombreux partages de code entre les applications Web et natives sur mobile/bureau.

Base de code partagée

Il existe des modèles pour permettre aux développeurs de commencer à utiliser Blazor avec .NET MAUI – le projet résultant apporte des artefacts Web Blazor dans les applications natives .NET MAUI. Bien qu’utile, un scénario plus réaliste consiste pour les développeurs à maintenir les applications Web créées avec Blazor, tout en proposant la même interface utilisateur sur les applications .NET MAUI natives. Cela est faisable en intégrant des projets Web Blazor (serveur/client/les deux) et des projets .NET MAUI avec Blazor, sous une seule solution, donc Blazor s’exécute partout à partir d’une base de code partagée.

Le menu du Finder pour Solution a BlazorEverywhere avec des entrées en dessous pour BlazorForNative qui est en gras, BlazorForWeb.Client, BlazorForWeb.Server, BlazorForWeb.Shared, BlazorSharedUI

L’objectif, cependant, n’est pas de réinventer la roue – les mêmes composants et styles Blazor devraient alimenter l’interface utilisateur pour les applications Web et natives. L’astuce consiste à déplacer les éléments partagés hors des projets Web Blazor ou .NET MAUI vers une bibliothèque de classes partagées référencée.

Encerclés sous BlazorSharedUI se trouvent les pages avec Counter.razor et Index.razor ;  Partagé avec MainLayout, NavMenu et SurveyPrompt ;  et wwwroot avec css, qui contient le dossier bootstrap, le dossier open-iconic et app.css

Variantes de plate-forme

C’est une belle histoire d’avoir partagé des composants/styles Blazor pour piloter une interface utilisateur commune sur les applications Web et natives. Cependant, un navigateur Web et des plates-formes telles que iOS/Android/Windows/macOS sont des facteurs de forme très différents, et l’interface utilisateur/UX ne devrait probablement pas être la même.

Blazor peut alimenter les expériences connectées sur le Web – exploiter les qualités de JavaScript selon les besoins ou prendre en charge les modèles d’hébergement sur serveur/client. Lors de l’exécution sur des applications mobiles/de bureau natives via .NET MAUI, Blazor peut faire des choses très spécifiques à la plate-forme.

En fin de compte, les applications Web et natives sont des toiles différentes – même si l’interface utilisateur partagée est alimentée par Blazor, les implémentations doivent varier. Ainsi, ce qui est demandé à partir d’une base de code partagée est une surface d’API commune pour la consommation, avec des différences d’implémentation spécifiques à la plate-forme. Cela ressemble beaucoup à ce pour quoi une métaphore de programmation clé est conçue – oui, des interfaces.

Aide sur les interfaces

Disons que Blazor alimente une interface utilisateur pour le Web et également des applications natives via .NET MAUI. Nous souhaitons afficher des informations sur le nom de l’appareil sur lequel l’application s’exécute, ce qui est très spécifique à la plate-forme sur le Web et sur mobile/bureau. Et nous voulons la taille de la fenêtre dans laquelle notre application est rendue, ainsi que des connotations très différentes entre les navigateurs Web et la WebView hébergée par .NET MAUI dans une application mobile/de bureau.

Nous voulons garder notre code propre avec une API cohérente, mais nous avons évidemment des implémentations différentes selon les plates-formes.

La première étape pourrait être de définir une interface dans notre bibliothèque d’interface utilisateur partagée, comme ceci :

Encerclé sous BlazorSharedUI est SharedServices avec IPlatformInfo.cs

using System;

namespace BlazorSharedUI.SharedServices
{
    public interface IPlatformInfo
    {
        public string GetPlatformName();
        public Task<string> GetWindowSize();
    }
}

Implémentation Web

Maintenant, cherchons à implémenter notre interface pour Blazor UI fonctionnant sur le Web, AKA dans un navigateur Web. Le moyen le plus simple d’obtenir les dimensions de la fenêtre d’un navigateur consiste à utiliser JavaScript. Écrivons-en donc quelques-unes dans un simple petit fichier déposé dans notre projet.

Encerclés sous BlazorForWeb.Client se trouvent les services avec BrowserService.cs et PlatformInfo.cs, et WindowDimension.js sous wwwroot

window.getDimensions = function() {
    return {
    width: window.innerWidth,
            height: window.innerHeight
        };
};

Comment notre code Blazor C# communique-t-il avec JavaScript ? Simple – il est intégré au runtime Blazor en tant qu’interopérabilité JavaScript. Nous pouvons invoquer JS à partir de .NET et .NET à partir de JS – utilisons notre fonction JS nouvellement définie à l’intérieur BrowserService classe, comme ceci :

using System;
using Microsoft.JSInterop;
using System.Threading.Tasks;

namespace BlazorForWeb.Client.Services
{
    public class BrowserService
    {
        private readonly IJSRuntime _js;

        public BrowserService(IJSRuntime js)
        {
            _js = js;
        }

        public async Task<BrowserDimension> GetDimensions()
        {
            return await _js.InvokeAsync<BrowserDimension>("getDimensions");
        }

    }

    public class BrowserDimension
    {
        public int Width { get; set; }
        public int Height { get; set; }
    }
}

Nous pouvons maintenant implémenter le code Interface for Blazor exécuté sur les navigateurs Web – le nom de la plate-forme est donné et nous pouvons récupérer la dimension de la fenêtre du navigateur à partir de BrowserService, qui à son tour appelle notre fonction JS.

using System;
using BlazorSharedUI.SharedServices;
using System.Threading.Tasks;

namespace BlazorForWeb.Client.Services
{
    public class PlatformInfo : IPlatformInfo
    {
        BrowserService myService;

        public PlatformInfo(BrowserService service)
        {
            myService = service;
        }

        public string GetPlatformName()
        {
            return "Browser";
        }

        public async Task<string> GetWindowSize()
        {
            var dimension = await myService.GetDimensions();
            int Height = dimension.Height;
            int Width = dimension.Width;
            string WindowDimension = Width + "x" + Height;

            return WindowDimension;
        }
    }
}

Implémentation native

Passons maintenant à l’implémentation de l’interface pour le code Blazor exécuté via .NET MAUI sur mobile/bureau. Même si l’interface utilisateur Blazor est rendue dans une WebView basée sur un navigateur, elle se trouve dans le shell d’une application véritablement native .NET MAUI.

C’est là que Blazor et .NET MAUI brillent ensemble – ils ont exactement le même runtime .NET. Ainsi, notre code Blazor C # peut exploiter les API .NET MAUI, résumées pour chaque plate-forme sur laquelle l’application s’exécute. Accéder au nom de l’appareil et aux dimensions de la fenêtre native est un jeu d’enfant avec les API .NET MAUI, comme ceci :

Encerclé sous BlazorForNative est Services avec PlatformInfo.cs

using System;
using BlazorSharedUI.SharedServices;

namespace BlazorForNative.Services
{
    public class PlatformInfo : IPlatformInfo
    {
        public string GetPlatformName()
        {
            return DeviceInfo.Current.Platform.ToString();
        }

        public Task<string> GetWindowSize()
        {
            double Width = DeviceDisplay.MainDisplayInfo.Width;
            double Height = DeviceDisplay.MainDisplayInfo.Height;

            string WindowSize = Width + "x" + Height;
            return Task.FromResult(WindowSize);
        }
    }
}

Interface utilisateur partagée

Avec les implémentations d’interface réalisées à la fois pour les applications Web et natives, il est temps de câbler les choses afin que nous tirions parti des implémentations. Avec les différences de plate-forme cachées, nous pouvons maintenant écrire un balisage générique Blazor/C # dans notre projet d’interface utilisateur partagée qui utilise les API d’interface cohérentes.

Encerclé sous BlazorSharedUI Pages avec Counter.razor et Index.razor, qui contient Index.razor.cs

Commençons par ajouter le nom de l’appareil et les informations sur les dimensions de la fenêtre au Index.razor page – il s’agit de l’interface utilisateur Blazor partagée pour l’application Web et .NET MAUI.

@page "https://www.telerik.com/" 

<PageTitle>Index</PageTitle>

<h1>Hello, World!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

Blazor running on Platform: @PlatformInfo?.GetPlatformName()
<br />
<br />
Window Dimensions: @_windowDimensions

Au lieu d’écrire C # intégré avec notre balisage HTML, nous pouvons facilement avoir un Index.razor.cs fichier qui contient le reste de la classe partielle – les conventions sont agréables. Ici, nous pouvons invoquer les méthodes Interface – les OnAfterRenderAsync() et
StateHasChanged() les déclencheurs sont utilisés pour que JS Interop de Blazor soit prêt à invoquer notre fonction JS pour les applications Web.

using System;
using BlazorSharedUI.SharedServices;
using Microsoft.AspNetCore.Components;

namespace BlazorSharedUI.Pages
{
    public partial class Index
    {
        [Inject]
        private IPlatformInfo? PlatformInfo { get; set; }

        private string? _windowDimensions;

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                _windowDimensions = await PlatformInfo?.GetWindowSize();
                StateHasChanged();
            }
        }
    }
}

Dernier point mais non le moindre, nous devons câbler les implémentations d’interface spécifiques à la plate-forme via l’injection de dépendances – voici comment dans l’application Web Blazor Programme.cs:

using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using BlazorForWeb.Client;
using BlazorForWeb.Client.Services;
using BlazorSharedUI.SharedServices;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<IPlatformInfo, PlatformInfo>();
builder.Services.AddScoped<BrowserService>();

await builder.Build().RunAsync();

Nous pouvons maintenant exécuter l’application Web Blazor localement et le tour est joué – l’interface utilisateur de Blazor s’affiche comme prévu et nous pouvons afficher le nom de la plate-forme et les dimensions de la fenêtre.

Application BlazorEverywhere avec des dimensions de fenêtre 1832x1040

Et voici l’injection de dépendances fournissant les implémentations d’interface câblées dans le .NET MAUI avec l’application Blazor Programme.cs:

using Microsoft.AspNetCore.Components.WebView.Maui;
using BlazorForNative.Data;
using BlazorSharedUI.SharedServices;
using BlazorForNative.Services;

namespace BlazorForNative;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

        builder.Services.AddMauiBlazorWebView();
#if DEBUG
        builder.Services.AddBlazorWebViewDeveloperTools();
#endif

        builder.Services.AddSingleton<WeatherForecastService>();
        builder.Services.AddScoped<IPlatformInfo, PlatformInfo>();

        return builder.Build();
    }
}

Nous devrions maintenant être prêts à exécuter notre application .NET MAUI sur n’importe quelle plate-forme choisie – sur iOS, Android, Windows, macOS. Il est amusant de voir la mise à jour du nom de l’appareil et des dimensions de la fenêtre spécifiques à la plate-forme pour divers simulateurs/appareils sur lesquels l’application s’exécute – l’interface utilisateur Blazor partagée puise dans les implémentations d’interface et les API .NET MAUI sur toutes les plates-formes.

Application BlazorEverywhere avec des dimensions de fenêtre 4096x2560

C’est la saison

C’est cette période de l’année – la saison des fêtes est à nos portes. Quoi que nous célébrions, essayons d’être joyeux et reconnaissants pour ce que nous avons. Un zélé vous avez peut-être acheté beaucoup de papier cadeau pour emballer des cadeaux pour vos proches – réutiliser c’est bien. Bien que les cadeaux puissent avoir la même apparence emballés, vous essaieriez de répondre aux besoins des personnes pour lesquelles vous emballez les cadeaux – leurs goûts comptent.

Blazor est naturellement le framework Web le plus excitant pour les développeurs .NET, permettant à C# de s’exécuter côté serveur ou entièrement côté client via WebAssembly. Et .NET MAUI inaugure la prochaine génération de développement multiplateforme natif sur .NET, atteignant sans effort les plateformes mobiles/de bureau à partir d’une seule base de code. Avec un composant d’interface utilisateur WebView moderne, .NET MAUI accueille Blazor en terre natale – les composants et les styles Web peuvent être rendus dans des applications natives sur iOS/Android/Windows/Mac.

Même si Blazor alimente l’interface utilisateur / UX sur les applications Web et natives, il peut y avoir des différences dans la façon dont les choses fonctionnent sur les plates-formes. Les interfaces génériques avec des implémentations spécifiques à la plate-forme peuvent permettre aux développeurs d’avoir un code partagé cohérent qui fonctionne différemment sur les plates-formes Web et mobiles/de bureau. Le partage entre les différences est bienveillant et maintient votre base de code sur la belle liste.




Source link

décembre 16, 2022