Extensibilité de Dataverse

Effectué

Dans cette rubrique, nous allons explorer les points d’extensibilité de Dataverse à la disposition des développeurs. L’architecture de Dataverse met en place une architecture axée sur les messages pour le traitement des requêtes. Chaque message de requête est traité au moyen d’un pipeline d’événements doté de points d’extension pour exécuter une logique métier personnalisée implémentée par des plug-ins. De nombreux messages sont fournis immédiatement et chaque fois qu’une table est créée, de nouveaux messages sont ajoutés pour prendre en charge cette table. En créant une API personnalisée, vous créez également un message.

Un concept clé est que, quel que soit le mode d’accès aux données, celles-ci sont toujours traitées comme un message par le pipeline d’événements, et toute logique métier personnalisée est exécutée. Cela est vrai que vous utilisiez l’interface utilisateur d’une application ou l’une des API, ou que vous effectuiez des opérations administratives telles que l’importation de données. Aucun moyen ne permet de modifier les données Dataverse directement qui contournent le système en cours d’exécution ou la logique personnalisée enregistrée.

Utilisation de l’API Dataverse

Dataverse fournit deux styles d’API permettant aux développeurs d’interagir avec les données : API web et service Organization. L’image suivante fournit une vue d’ensemble de chacun :

API web Dataverse

L’API web est disponible sur un point de terminaison OData v4 RESTful. Utilisez cette option pour tout langage de programmation prenant en charge les requêtes HTTP et l’authentification à l’aide d’OAuth 2.0. Trouvez d’autres exemples.

Service Dataverse Organization

Le service Organization est un kit de développement logiciel (SDK) .NET avec des assemblys .NET fournis par Microsoft avec des générateurs de classes typées pour les classes de table.

En cas de service Organization provenant d’un plug-in Dataverse, le service est instancié et disponible pour le code du plug-in sans qu’il soit nécessaire de s’authentifier. Vous pouvez obtenir une instance de la logique de votre plug-in à l’aide du paramètre serviceProvider transmis au plug-in pour obtenir une instance de la fabrique du service Organization (IOrganizationService). À l’aide de la fabrique, vous pouvez obtenir une instance du service Organization. Ce qui suit est un exemple d’un plug-in simple qui récupère une instance lui permettant de créer une ligne de table Compte.

public void Execute(IServiceProvider serviceProvider)
{
    IPluginExecutionContext pluginContext = serviceProvider.Get<IPluginExecutionContext>();
    IOrganizationServiceFactory factory = serviceProvider.Get<IOrganizationServiceFactory>();
    IOrganizationService orgService = serviceProvider.GetOrganizationService(pluginContext.UserId);

    Entity newAccount = new Entity("account");                  
    newAccount["name"] = "Fourth Coffee";
    Guid accountid = orgService.Create(newAccount);
}

Vous pouvez également utiliser le service Organization en dehors des plug-ins, par exemple à partir d’un portail personnalisé ASP.NET, d’une fonction Azure Functions, voire d’une application console. À partir de ce type d’applications, vous pouvez utiliser le service Organization de Dataverse ServiceClient, qui prend en charge les applications utilisant .NET Full Framework 4.6.2, 4.7.2, 4.8 et .NET Core 3.0, 3.1, 5.0, 6.0. La classe ServiceClient implémente l’interface IOrganizationService. ServiceClient implémente également IOrganizationServiceAsync2, qui rend aussi disponibles des versions asynchrones des méthodes.

L’exemple suivant obtient une instance de ServiceClient et crée une ligne de table Compte.

ServiceClient serviceClient =
    new ServiceClient("Url=https://yourenv.crm.dynamics.com;AuthType=OAuth;AppId=51f81489-12ee-4a9e-aaae-a2591f45987d;RedirectUri=http://localhost ;LoginPrompt=Always");

    Entity newAccount = new Entity("account");                  
    newAccount["name"] = "Fourth Coffee";
    Guid accountid = serviceClient.Create(newAccount);

D’autres exemples d’utilisation du service Organization sont disponibles. Vous pouvez également en savoir plus sur les chaînes de connexion et les options disponibles.

Les API prennent en charge leurs propres approches pour créer des requêtes de données en sus de la prise en charge de FetchXML. FetchXML est un langage de requête propriétaire utilisé dans Dataverse. Le langage FetchXML permet de créer des requêtes complexes sur des tables liées et d’utiliser des conditions et opérateurs spécifiques à Dataverse. Le connecteur Power Automate Dataverse prend également en charge FetchXML.

Pipeline d’événements

Lorsque vous effectuez une action telle que créer un enregistrement dans une application ou créer un enregistrement à l’aide de l’API, un message Créer est traité par Dataverse. Le message est traité dans le pipeline d’événements qui fournit un ensemble cohérent d’étapes par lesquelles le message passe. Chaque étape, à l’exception de l’opération principale, peut être associée à un plug-in pour exécuter une logique personnalisée. Voici les phases prises en charge lorsqu’un message commence par le haut et progresse à travers les phases du pipeline :

Schéma des phases prises en charge lorsqu’un message commence par le haut et progresse à travers le pipeline.

Avoir une bonne compréhension de la façon dont les messages sont traités peut vous aider à comprendre les comportements et comment et où mettre en œuvre au mieux une logique personnalisée. Comprendre le pipeline est également essentiel pour reconnaître comment les plug-ins et les API personnalisées s’intègrent. En savoir plus sur les détails de l’infrastructure d’événements

Création de plug-ins

Les plug-ins sont des classes .NET qui implémentent une interface IPlugin fournie par les assemblys SDK de Dataverse. Cette interface nécessite que vous implémentiez une seule méthode nommée Execute. Voici un exemple de l’implémentation minimale :

    public sealed class MyFirstPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
               //Business Logic 
         }
    }

La méthode Execute a un paramètre de type IServiceProvider. Cette interface a une méthode GetService que vous pouvez utiliser pour récupérer les services disponibles pour un plug-in. Voici des exemples de services disponibles :

  • IPluginExecutionContext : cela vous donne accès au message en cours de traitement et aux informations sur le demandeur.

  • ITracingService : cela vous donne accès à l’écriture dans le journal de suivi à des fins de diagnostic.

  • IOrganizationServiceFactory : cela vous donne un accès pour récupérer un OrganisationService permettant d’accéder aux données à partir du plug-in.

Voici un exemple d’obtention du contexte d’exécution à l’aide de GetService :

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

L’utilisation de context.InputParameters peut vous donner accès au message d’origine et le contexte.OutputParameters peut vous donner accès à ce qui est renvoyé à l’appelant.

Une bonne compréhension du contexte d’exécution est fondamentale pour un développeur de plug-in. En savoir plus sur le contexte d’exécution

Afin qu’un plug-in s’exécute, il doit être enregistré pour s’exécuter pour un message spécifique. Ceci peut être réalisé à l’aide de l’outil Plugin Registration Tool.

API personnalisées

Les opérations dans Dataverse sont définies comme des messages. Les API personnalisées offrent un moyen basé sur le code pour définir de nouveaux messages que vous pouvez étendre dans les services web Dataverse. Ces messages peuvent ensuite être appelés, tout comme les messages système, mais pour exécuter une logique métier personnalisée. Par exemple, si vous avez des exigences spécifiques pour rechercher un client à l’aide d’une séquence prédéfinie d’appels d’API, au lieu de demander à chaque appelant d’API d’implémenter cette séquence, vous pouvez implémenter une API personnalisée findcustomer. L’API findcustomer implémente désormais la logique requise pour rechercher le client et renvoyer les résultats. Ainsi, au lieu que chaque application doive trouver comment rechercher un client et le faire de manière incohérente, elle pourrait appeler l’API personnalisée qui traiterait les demandes de recherche de la même manière à chaque fois. Et si des changements sont nécessaires, ils devraient être mis en œuvre à un seul endroit.

Pour définir une nouvelle API personnalisée, vous commencez par créer un enregistrement d’API personnalisé. Cela peut être fait via le portail des créateurs, via le code ou en utilisant les solutions Dataverse. Dans le cadre de la création de l’enregistrement, vous identifiez le nom de l’API personnalisée et les paramètres de requête et de réponse.

Pour implémenter la logique de l’API personnalisée, vous créez un plug-in et vous l’enregistrez à l’étape Opération principale du pipeline. L’implémentation de l’API personnalisée est le seul scénario dans lequel un plug-in peut être enregistré sur la phase Opération principale. Vous verrez un exemple de cette opération plus tard dans l’exercice.

Une fois implémenté, vous pouvez utiliser le message personnalisé depuis les API Dataverse, Power Apps et Power Automate. Ce qui suit est un exemple d’utilisation de l’API personnalisée findcustomer à partir de C#.

var req = new OrganizationRequest("fabrikam_findcustomer")
{
    ["CustomerName"] = "Contoso",
    ["CustomerAddress"] = "1 Redmond Way"
};

var resp = serviceClient.Execute(req);

Vous ne pouvez pas non plus implémenter un plug-in et autoriser l’utilisation de l’API personnalisée pour déclencher une autre automatisation. Par exemple, la création d’une API personnalisée comportant des données sur un événement survenu dans un autre système permet à ce système d’appeler cette API dans Dataverse, où de nombreux points d’intégration différents avec Azure ou Web Hooks, ou Power Automate, ou des plug-ins asynchrones sur l’API pourront lancer d’autres automatisations.