Étendre votre application avec des services, des extensions et des packages

Windows fournit plusieurs technologies qui permettent à votre application de fournir des fonctionnalités à d’autres applications ou d’utiliser des compléments tiers. Cet article compare les options d’extensibilité disponibles pour les applications de bureau SDK d'application Windows.

Vue d’ensemble des options d’extensibilité

Technologie Description Identité de package requise Système d’exploitation minimal
Services d’application Communication de demande/réponse entre les applications via AppServiceConnection Oui Windows 10 1607
Extensions d'application Modèle de plug-in : l’application hôte découvre du contenu à partir de packages d’extension Oui Windows 10 1607
Extensions de package Extensibilité au niveau du package plus large avec uap17:PackageExtension Oui Windows 11
Packages facultatifs Packages de contenu supplémentaires qui complètent une application principale Oui Windows 10 1709
Packages de ressources Ressources de langue, d’échelle et d’accessibilité séparées par le marché Oui Windows 10

Choix de la technologie appropriée

Utiliser les services d’application quand

  • Vous avez besoin d’une communication bidirectionnelle entre des applications distinctes.
  • L’application consommateur envoie une demande et attend une réponse.
  • Vous souhaitez exposer une interface de type API à d’autres applications.

Exemple : service de traduction que d’autres applications peuvent appeler pour traduire du texte.

Utiliser des extensions d’application quand

  • Votre application a besoin d’un modèle de plug-in où des tiers fournissent du contenu, des thèmes ou des compléments.
  • Les extensions sont découvertes au moment de l’exécution à partir de packages installés.
  • Les extensions fournissent des données ou une configuration, et non du code exécutable (l’exécution du code doit utiliser les services d’application).

Exemple : Éditeur d’images qui découvre les packs de filtre à partir de packages d’extension installés.

Utiliser des extensions de paquet lorsque

  • Vous avez besoin d’une extensibilité plus large au niveau du package sur Windows 11.
  • Les extensions doivent accéder à plus de contenu de package que le modèle l’autorise PublicFolder .

Utiliser des paquets facultatifs lorsque

  • Vous disposez d’un contenu supplémentaire (DLC, fonctionnalités Premium) distribué en tant que packages distincts.
  • Le contenu est créé par le même éditeur.

Modèles d’architecture

App Service avec découverte d’extensions

Combinez les extensions d’application avec les services d’application pour une architecture de plug-in complète :

  1. Votre application hôte utilise AppExtensionCatalog pour découvrir les extensions installées.
  2. Chaque extension déclare des propriétés qui décrivent ses fonctionnalités.
  3. Lorsque l’utilisateur active une extension, l’application hôte se connecte au service d’application de l’extension pour la communication bidirectionnelle.
┌─────────────────┐      ┌──────────────────┐
│   Host app       │      │  Extension app    │
│                  │      │                   │
│ AppExtension     │◄────►│ AppExtension      │
│   Catalog        │      │   declaration     │
│                  │      │                   │
│ AppService       │◄────►│ AppService        │
│   Connection     │      │   provider        │
└─────────────────┘      └──────────────────┘

Extension de contenu uniquement

Pour des scénarios plus simples où les extensions fournissent du contenu statique (thèmes, modèles, fichiers de données) :

  1. L’application hôte découvre les extensions via AppExtensionCatalog.
  2. Il lit les fichiers depuis PublicFolder de l’extension.
  3. Aucun service d’application n’est nécessaire.

Différences par rapport à l’extensibilité UWP

Les technologies d’extensibilité décrites ici fonctionnent de la même façon dans SDK d'application Windows applications de bureau que dans UWP, avec une exigence : identité de package MSIX. Toutes les fonctionnalités d’extensibilité s’appuient sur le manifeste du package pour les déclarations et le catalogue de packages pour la découverte.

Si votre application de bureau n’est pas empaquetée, vous ne pouvez pas utiliser ces technologies d’extensibilité. Envisagez d’autres approches telles que :

  • Interfaces de modules d’extension basées sur COM
  • Découverte d’extensions basées sur le système de fichiers
  • Canaux nommés ou autres mécanismes d’IPC

Découverte de plug-ins basé sur des fichiers pour les applications non empaquetées

Pour les applications WinUI 3 non empaquetées, vous pouvez implémenter un système de plug-in à l'aide de AssemblyLoadContext .NET pour charger des extensions à partir d'un dossier connu :

public class PluginLoader
{
    private readonly string _pluginDirectory;

    public PluginLoader(string pluginDirectory)
    {
        _pluginDirectory = pluginDirectory;
    }

    public IEnumerable<T> LoadPlugins<T>() where T : class
    {
        if (!Directory.Exists(_pluginDirectory))
            yield break;

        foreach (var dll in Directory.GetFiles(_pluginDirectory, "*.dll"))
        {
            var context = new PluginLoadContext(dll);
            var assembly = context.LoadFromAssemblyPath(Path.GetFullPath(dll));

            foreach (var type in assembly.GetTypes()
                .Where(t => typeof(T).IsAssignableFrom(t) && !t.IsAbstract))
            {
                if (Activator.CreateInstance(type) is T plugin)
                    yield return plugin;
            }
        }
    }
}

// Custom AssemblyLoadContext to isolate plugin dependencies
public class PluginLoadContext : AssemblyLoadContext
{
    private readonly AssemblyDependencyResolver _resolver;

    public PluginLoadContext(string pluginPath) : base(isCollectible: true)
    {
        _resolver = new AssemblyDependencyResolver(pluginPath);
    }

    protected override Assembly? Load(AssemblyName assemblyName)
    {
        var path = _resolver.ResolveAssemblyToPath(assemblyName);
        return path != null ? LoadFromAssemblyPath(path) : null;
    }
}

Warning

Le chargement d’assemblys à partir d’un disque sans validation est un risque de sécurité. En production, vérifiez les signatures d’assembly (telles que Authenticode) avant le chargement, limitez les autorisations ACL du répertoire de plug-in et envisagez d’exécuter des plug-ins dans un processus distinct avec des privilèges réduits.

Définissez un contrat d’interface partagée dans un assembly distinct que l’hôte et les plug-ins référencent :

// Contoso.App.Contracts (shared assembly)
public interface IPluginExtension
{
    string Name { get; }
    string Description { get; }
    void Execute(IServiceProvider services);
}

Note

L’utilisation isCollectible: true dans le fichier AssemblyLoadContext vous permet de décharger des plug-ins au moment de l’exécution. Cette approche évite les problèmes de gestion des versions que MEF (Managed Extensibility Framework) peut introduire dans les applications de bureau.