Écrire un plug-in

Vous pouvez créer des plug-ins en utilisant l’une des méthodes suivantes :

  • Les outils de développement de Power Platform offrent un moyen moderne de créer des plug-ins. Les outils auxquels il est fait référence ici sont Power Platform Tools pour Visual Studio et la CLI Power Platform. Ces deux Power Platform Tools génèrent un code de plug-in similaire, de sorte que passer d’un outil à l’autre est assez facile et compréhensible.

    • Utilisez Power Platform Tools pour Visual Studio pour créer rapidement un code de plug-in de modèle et enregistrer (déployer) un plug-in. Un article de démarrage rapide est disponible pour vous montrer comment procéder. Utilisez cet outil si vous aimez travailler dans Visual Studio.

    • Utilisez la CLI Power Platform pour créer un projet de plug-in de base (compatible Visual Studio) avec un modèle de code de plug-in à l’aide d’une seule commande pac plugin. Ensuite, à l’aide de la commande pac tool prt, vous utilisez de manière interactive l’outil d’inscription des plug-ins pour inscrire votre création auprès de Microsoft Dataverse. Utilisez cet ensemble d’outils CLI si vous aimez travailler dans une fenêtre de terminal ou dans Visual Studio Code.

  • Écrivez du code manuellement à l’aide de Visual Studio ou de votre éditeur préféré. Cet article se concentre sur l’écriture de code à l’aide des API Dataverse. Toutefois, les concepts introduits s’appliquent également au développement de plug-ins à l’aide de nos outils mentionnés précédemment.

Interface IPlugin

Un plug-in est une classe compilée dans un assembly créé pour cibler .NET Framework 4.6.2. Chaque classe du projet de plug-in qui est enregistrée comme étape du pipeline de l’événement doit implémenter l’interface IPlugin qui nécessite une méthode IPlugin.Execute unique.

public class MyPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        throw new NotImplementedException();
    }
}

La méthode Execute accepte un seul paramètre IServiceProvider. L’interface IServiceProvider a une seule méthode : GetService. Utilisez cette méthode pour obtenir plusieurs types de services que vous pouvez utiliser dans votre code.

Pour plus d’informations, voir : Services que vous pouvez utiliser dans votre code

Important

Lorsqu’elle dérive de IPlugin, la classe doit être écrite stateless. car la plateforme met en cache une instance de classe et la réutilise pour des raisons de performances. En termes simples, vous ne devez ajouter aucune propriété ou méthode à la classe et tout doit être inclus dans la méthode Execute.

Lors de l’utilisation de l’extension Power Platform Tools ou de Power Platform CLI pour la création de plug-ins, la classe PluginBase générée implémente l’interface IPlugin.

Il existe quelques exceptions à l’instruction concernant l’ajout de propriétés ou de méthodes dans la note ci-dessus. Par exemple, vous pouvez avoir une propriété qui représente une constante et vous pouvez avoir des méthodes qui sont appelées à partir de la méthode Execute. L’important est de ne jamais stocker une instance de service ou des données de contexte en tant que propriété dans votre classe. Ces valeurs changent avec chaque appel et vous ne voulez pas que les données soient mises en cache et appliquées aux appels suivants.

Pour plus d’informations, voir : Développer les implémentations IPlugin en mode sans état

Transmettre des données de configuration à votre plug-in

Lorsque vous inscrivez un plug-in, vous pouvez éventuellement spécifier des données de configuration à transmettre au plug-in lors de l’exécution. Les données de configuration vous permettent de définir le comportement d’une instance spécifique d’un plug-in enregistré. Ces informations sont transmises en tant que données de chaîne aux paramètres dans le constructeur de votre classe. Il existe deux paramètres, nommés unsecure et secure. Utilisez le premier paramètre unsecure pour les données qui peuvent être visualisées par les utilisateurs. Utilisez le deuxième paramètre secure pour les données sensibles.

Le code suivant présente les trois signatures de constructeur possibles pour une classe de plug-in nommée MyPlugin.

public MyPlugin() {}
public MyPlugin(string unsecure) {}  
public MyPlugin(string unsecure, string secure) {}

Les données de configuration sécurisées sont stockées dans une table distincte que seuls les administrateurs système peuvent lire.

Plus d’informations : Enregistrer une étape de plug-in > Définir des données de configuration

Classe abstraite PluginBase

La classe PluginBase implémente l’interface IPlugin. Nous proposons cette classe car elle implémente un modèle de programmation robuste qui a fait ses preuves dans les solutions commerciales. Cependant, l’utilisation de cette classe dans le code de votre plug-in est facultative mais recommandée.

La classe n’est disponible dans aucun assembly SDK ; vous devez générer la classe en utilisant l’un de nos outils. Pour générer la classe, créez un projet de plug-in dans l’extension Power Platform Tools pour Visual Studio ou exécutez la commande pac plugin init de Power Platform CLI. Vous trouverez un fichier PluginBase.cs dans le projet généré.

Pour plus d’informations : pac plugin, Démarrage rapide : créer un plug-in à l’aide de Power Platform Tools

Important

La classe PluginBase générée par l’extension Power Platform Tools et Power Platform CLI ont des signatures de membres de classe légèrement différentes. Il est préférable de choisir l’une ou l’autre et de s’y tenir dans tout le développement du code de votre plug-in. Les deux versions de la classe ont les mêmes fonctionnalités et fonctionnent de manière similaire.

Ce diagramme de classes fournit un visuel sur les interfaces et les classes clés associées à PluginBase.

Classe PluginBase et autres types associés.

L’exemple de classe Plugin1 (dans le diagramme) dérive de PluginBase. Vous renommez cette classe Plugin1 en votre propre nom personnalisé et ajoutez du code pour implémenter la méthode ExecuteDataversePlugin et le constructeur de classe. La classe LocalPluginContext est automatiquement initialisée avec les références de service indiqués et les points de terminaison disponibles pour votre plug-in. Si vous implémentiez l’interface IPlugin, vous devez écrire du code pour initialiser tous ces services et points de terminaison avant de les utiliser.

Services que vous pouvez utiliser dans votre code

De manière générale, dans votre plug-in, vous devrez :

  • accéder aux données contextuelles transmises à votre plug-in pour déterminer les informations sur l’entité et la requête de message qui ont provoqué l’événement et appelé votre plug-in ; Ces données sont appelées le contexte d’exécution.
  • accéder au service Web de l’organisation à l’aide des appels SDK pour .NET pour effectuer des opérations de requête de message telles que requête, création, mise à jour, suppression, etc. ;
  • écrire des messages au service de traçage pour pouvoir évaluer l’exécution de code de votre plug-in.

Notes

Tous les services Dataverse utilisés normalement par votre plug-in et le contexte d’exécution du plug-in sont préconfigurés et disponibles pour le code de votre plug-in lorsque vous dérivez votre plug-in de la classe PluginBase.

L’attribut IServiceProvider.GetService vous permet d’accéder aux références de service transmises dans le contexte d’exécution lorsque cela est nécessaire. Pour obtenir une instance d’un service, appelez la méthode GetService en passant le type de service. Lisez plus d’informations sur cette méthode dans les sections suivantes.

Contexte d’exécution

Le contexte d’exécution contient une multitude d’informations dont un plug-in peut avoir besoin. Le contexte est obtenu à l’aide du code suivant.

IPluginExecutionContext context = (IPluginExecutionContext)
    serviceProvider.GetService(typeof(IPluginExecutionContext));

Pour plus d’informations : IPluginExecutionContext, Comprendre le contexte d’exécution

Service web d’organisation

Outre les données transmises dans le contexte d’exécution, les données des lignes de table Dataverse peuvent être lues ou écrites à partir du code du plug-in à l’aide d’appels du SDK au service Web de l’organisation. N’essayez pas d’utiliser l’API web, car elle n’est pas prise en charge dans les plug-ins. De plus, n’authentifiez pas l’utilisateur avant d’accéder aux services Web, car l’utilisateur est pré-authentifié avant l’exécution du plug-in.

Pour plus d’informations : Opérations sur les tables, Utiliser les messages

Pour obtenir une référence d’objet au service Web de l’organisation, utilisez le code suivant :

IOrganizationServiceFactory serviceFactory =
    (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService orgService = serviceFactory.CreateOrganizationService(context.UserId);

Service de traçage

Utilisez le service de suivi pour écrire des messages à la table PluginTraceLog afin de pouvoir examiner les journaux pour comprendre ce qui s’est produit pendant l’exécution du plug-in.

Important

Vous devez d’abord activer la journalisation du suivi dans votre environnement avant de pouvoir écrire dans les journaux ou les afficher. Pour plus d’informations : Traçage et journalisation

Pour écrire dans le journal de suivi, vous devez obtenir une instance du service de suivi. Le code suivant montre comment obtenir une instance du service de suivi à l’aide de la méthode IServiceProvider.GetService .

ITracingService tracingService =
    (ITracingService)serviceProvider.GetService(typeof(ITracingService));

Pour écrire dans le journal de suivi, utilisez la méthode ITracingService.Trace .

tracingService.Trace("Write {0} {1}.", "your", "message");

Informations complémentaires : Utiliser le suivi, Traçage et enregistrement.

Autres services

Lorsque vous écrivez un plug-in qui utilise l’intégration Azure Service Bus, vous utilisez un service de notification qui implémente l’interface IServiceEndpointNotificationService, mais cette interface ne sera pas décrite ici.

Pour plus d’informations, voir : Intégration d’Azure

Pour résumer

L’application des concepts de plug-in détaillés précédemment génère un code de plug-in qui ressemble à ce qui suit.

public class MyPlugin : PluginBase
{
  // Constructor
  public MyPlugin(string unsecureConfiguration, string secureConfiguration)
       : base(typeof(MyPlugin))
  { }

  protected override void ExecuteDataversePlugin(ILocalPluginContext localPluginContext)
  {
    if (localPluginContext == null)
    {
      throw new ArgumentNullException(nameof(localPluginContext));
    }

    var context        = localPluginContext.PluginExecutionContext;
    var serviceFactory = localPluginContext.OrgSvcFactory;
    var tracingService = localPluginContext.TracingService;

    try
    {
      // TODO Plug-in business logic goes here. You can access data in the context,
      // and make calls to the Organization web service using the Dataverse SDK.
    }
    catch (FaultException<OrganizationServiceFault> ex)
    {
      throw new InvalidPluginExecutionException("The following error occurred in MyPlugin.", ex);
    }
    catch (Exception ex)
    {
        tracingService.Trace("MyPlugin: error: {0}", ex.ToString());
        throw;
    }
  }
}

Vous pouvez consulter ces deux méthodes d’implémentations de plug-in dans notre exemple de code FollowupPlugin. Pour plus d’informations sur la gestion des exceptions dans les plug-ins, consultez Gérer les exceptions dans les plug-ins.

La conception du plug-in a un impact sur les performances

Lors de l’écriture de votre plug-in, il est essentiel qu’il s’exécute efficacement et rapidement. Quelle que soit la durée d’exécution de votre plug-in, l’utilisateur final qui a appelé l’opération message (qui a déclenché votre plug-in) doit attendre. Outre le traitement de l’opération message, Dataverse exécute tous les plug-ins synchrones inscrits dans le pipeline, y compris votre plug-in. Lorsque les plug-ins prennent trop de temps à s’exécuter, ou si trop de plug-ins sont enregistrés dans un pipeline, l’impact sur les performances peut entraîner une interface utilisateur d’application qui ne répond pas ou, dans le pire des cas, une erreur de délai d’attente avec la restauration du pipeline.

Important

Les plug-ins doivent respecter une limite de temps d’exécution et des contraintes de ressources. Pour plus d’informations : Analyser les performances du plug-in

Utilisation de types à liaison anticipée dans le code du plug-in

Vous pouvez en option utiliser des types à liaison anticipée dans le code du plug-in. Incluez simplement le fichier des types généré dans votre projet de plug-in. Tous les types de table fournis dans la collection InputParameters du contexte d’exécution sont des types à liaison tardive. Vous devrez convertir ces types à liaison tardive en types à liaison anticipée.

Par exemple, vous pouvez effectuer les opérations suivantes lorsque vous savez que le paramètre Target représente une table de compte. Dans cet exemple, « Account » est un type à liaison anticipée.

Account acct = context.InputParameters["Target"].ToEntity<Account>();

Mais vous ne devez jamais essayer de définir la valeur avec un type à liaison anticipée. Cela provoque une SerializationException.

context.InputParameters["Target"] = new Account() { Name = "MyAccount" }; // WRONG: Do not do this. 

Voir aussi

Gérer les exceptions
Enregistrer un plug-in
Déboguer des plug-ins
Didacticiel : Écrire et enregistrer un plug-in
Meilleures pratiques et directives concernant le développement de plug-ins et de workflows

Notes

Pouvez-vous nous indiquer vos préférences de langue pour la documentation ? Répondez à un court questionnaire. (veuillez noter que ce questionnaire est en anglais)

Le questionnaire vous prendra environ sept minutes. Aucune donnée personnelle n’est collectée (déclaration de confidentialité).