Skip to content

Plugin System ​

Package : RVR.Framework.Plugins

Description ​

Systeme de plugins base sur NuGet pour RIVORA Framework. Permet la decouverte, l'installation, la verification et le chargement automatique de plugins, avec validation de compatibilite et verification de signature.

Enregistrement ​

csharp
builder.Services.AddRvrPluginSystem(builder.Configuration);

Configuration ​

json
{
  "Plugins": {
    "Enabled": true,
    "AutoDiscovery": true,
    "PluginDirectory": "./plugins",
    "NuGet": {
      "Sources": [
        "https://api.nuget.org/v3/index.json"
      ],
      "PackagePrefix": "RVR.Plugin.",
      "AllowPrerelease": false
    },
    "Signature": {
      "VerifySignatures": true,
      "AllowUnsigned": false,
      "TrustedSigners": ["Rivora", "KhalilBenazzouz"]
    },
    "Compatibility": {
      "StrictVersionCheck": true,
      "MinimumRivoraVersion": "3.0.0"
    }
  }
}

Interface IRvrPlugin ​

csharp
/// <summary>
/// Interface principale pour les plugins RIVORA.
/// Etend IPlugin avec des metadonnees specifiques au framework.
/// </summary>
public interface IRvrPlugin : IPlugin
{
    /// <summary>Version minimale de RIVORA requise.</summary>
    string MinimumRivoraVersion { get; }

    /// <summary>Liste des dependances (autres plugins requis).</summary>
    IReadOnlyList<string> Dependencies { get; }

    /// <summary>Metadonnees du plugin.</summary>
    PluginMetadata Metadata { get; }
}

public interface IPlugin
{
    string Name { get; }
    string Version { get; }
    string Description { get; }

    Task InitializeAsync(IServiceProvider services, CancellationToken ct = default);
    Task ShutdownAsync(CancellationToken ct = default);
}

public record PluginMetadata(
    string Author,
    string? ProjectUrl = null,
    string? LicenseUrl = null,
    IReadOnlyList<string>? Tags = null);

Composants principaux ​

NuGetPluginDiscovery ​

Recherche les packages NuGet correspondant au prefixe RVR.Plugin.* :

csharp
public class NuGetPluginDiscovery
{
    /// <summary>Rechercher des plugins disponibles sur NuGet.</summary>
    Task<IReadOnlyList<PluginInfo>> SearchAsync(
        string? query = null, CancellationToken ct = default);

    /// <summary>Obtenir les details d'un plugin specifique.</summary>
    Task<PluginInfo?> GetInfoAsync(
        string packageId, CancellationToken ct = default);
}

public record PluginInfo(
    string PackageId,
    string LatestVersion,
    string Description,
    string Author,
    long DownloadCount,
    bool IsSigned);

PluginInstaller ​

Installe et desinstalle les plugins depuis NuGet :

csharp
public class PluginInstaller
{
    /// <summary>Installer un plugin depuis NuGet.</summary>
    Task<InstallResult> InstallAsync(
        string packageId, string? version = null, CancellationToken ct = default);

    /// <summary>Desinstaller un plugin.</summary>
    Task<bool> UninstallAsync(
        string packageId, CancellationToken ct = default);

    /// <summary>Lister les plugins installes.</summary>
    Task<IReadOnlyList<InstalledPlugin>> ListInstalledAsync(
        CancellationToken ct = default);

    /// <summary>Mettre a jour un plugin vers la derniere version.</summary>
    Task<InstallResult> UpdateAsync(
        string packageId, CancellationToken ct = default);
}

PluginSignatureVerifier ​

Verifie la signature NuGet des packages :

csharp
public class PluginSignatureVerifier
{
    /// <summary>Verifier la signature d'un package plugin.</summary>
    Task<SignatureResult> VerifyAsync(
        string packagePath, CancellationToken ct = default);
}

public record SignatureResult(
    bool IsValid,
    bool IsSigned,
    string? SignerName,
    string? Reason);

PluginCompatibilityChecker ​

Valide la compatibilite avec la version courante de RIVORA :

csharp
public class PluginCompatibilityChecker
{
    /// <summary>Verifier qu'un plugin est compatible avec la version actuelle.</summary>
    CompatibilityResult Check(IRvrPlugin plugin);
}

public record CompatibilityResult(
    bool IsCompatible,
    string? RequiredVersion,
    string? CurrentVersion,
    IReadOnlyList<string>? MissingDependencies);

Utilisation ​

Decouvrir et installer des plugins ​

csharp
public class PluginManagerService
{
    private readonly NuGetPluginDiscovery _discovery;
    private readonly PluginInstaller _installer;
    private readonly PluginSignatureVerifier _verifier;

    public async Task<IReadOnlyList<PluginInfo>> RechercherPluginsAsync(CancellationToken ct)
    {
        return await _discovery.SearchAsync(query: null, ct);
    }

    public async Task InstallerPluginAsync(string packageId, CancellationToken ct)
    {
        // 1. Recuperer les informations
        var info = await _discovery.GetInfoAsync(packageId, ct);
        if (info is null)
            throw new InvalidOperationException($"Plugin {packageId} introuvable.");

        // 2. Installer depuis NuGet
        var result = await _installer.InstallAsync(packageId, ct: ct);
        if (!result.Success)
            throw new InvalidOperationException($"Echec d'installation : {result.Error}");

        // 3. Verifier la signature
        var signature = await _verifier.VerifyAsync(result.PackagePath, ct);
        if (!signature.IsValid)
        {
            await _installer.UninstallAsync(packageId, ct);
            throw new SecurityException($"Signature invalide pour {packageId}");
        }
    }
}

Lister les plugins installes ​

csharp
public async Task<IActionResult> GetInstalledPlugins(CancellationToken ct)
{
    var plugins = await _installer.ListInstalledAsync(ct);
    return Ok(plugins.Select(p => new
    {
        p.PackageId,
        p.Version,
        p.Description,
        p.InstalledAt
    }));
}

Auto-decouverte par assembly scanning ​

Lorsque AutoDiscovery est active, RIVORA scanne automatiquement les assemblies dans le repertoire PluginDirectory et enregistre tous les types implementant IRvrPlugin :

csharp
// Au demarrage, les plugins sont decouverts et initialises automatiquement
builder.Services.AddRvrPluginSystem(builder.Configuration);

// Equivalent manuel :
builder.Services.AddRvrPluginSystem(options =>
{
    options.AutoDiscovery = true;
    options.PluginDirectory = "./plugins";
    options.OnPluginLoaded = (plugin, sp) =>
    {
        Console.WriteLine($"Plugin charge : {plugin.Name} v{plugin.Version}");
    };
});

Creer un plugin ​

Creez un projet de classe library ciblant .NET 9 :

csharp
public class MonPlugin : IRvrPlugin
{
    public string Name => "MonPlugin";
    public string Version => "1.0.0";
    public string Description => "Un plugin personnalise pour RIVORA";
    public string MinimumRivoraVersion => "3.0.0";
    public IReadOnlyList<string> Dependencies => Array.Empty<string>();
    public PluginMetadata Metadata => new(
        Author: "Mon Equipe",
        ProjectUrl: "https://github.com/mon-equipe/mon-plugin",
        Tags: new[] { "custom", "example" });

    public async Task InitializeAsync(IServiceProvider services, CancellationToken ct)
    {
        var logger = services.GetRequiredService<ILogger<MonPlugin>>();
        logger.LogInformation("MonPlugin initialise avec succes");

        // Enregistrer vos services, middleware, etc.
    }

    public Task ShutdownAsync(CancellationToken ct)
    {
        // Nettoyage des ressources
        return Task.CompletedTask;
    }
}

Publiez le package avec le prefixe RVR.Plugin. sur NuGet pour qu'il soit decouvert automatiquement.

Voir l'exemple complet dans samples/custom-plugin.

Fonctionnalites cles ​

  • Decouverte NuGet : Recherche automatique des packages RVR.Plugin.*
  • Installation / Desinstallation : Gestion complete du cycle de vie des plugins
  • Verification de signature : Validation des signatures NuGet pour la securite
  • Compatibilite : Verification de la version minimale de RIVORA et des dependances
  • Auto-decouverte : Chargement automatique via assembly scanning au demarrage
  • Metadonnees enrichies : Auteur, URL, licence, tags pour chaque plugin
  • Extensible : Interface IRvrPlugin simple a implementer

Released under the MIT License.