Développeurs et architectes, vous créez une application avec Dynamics 365? Comment veiller à cibler les cas dutilisation selon le contexte d’affaires et non selon la méthode utilisée pour y parvenir? Pour ce faire, découvrez linjection de dépendances et linversion de contrôle.

 

Orientation typique Détails de mise en œuvre masquant le cas dutilisation 

Je me concentrerai sur la mise en œuvre de ce concept dans Dynamics 365, car la rédaction des plugins correspondants pose un certain défi. En effet, l’architecture d’un plugin semble résister à l’inversion de contrôle.

Voici un exemple : à la création d’un compte, nous voulons créer une tâche pour faire le suivi dans une semaine avec le titulaire (il s’agit d’un exemple de plugin tiré du kit de développement logiciel de Dynamics 365, simplifié via la PluginBase de mon collègue David Rivard). Normalement, à la création d’un plugin, on se concentre sur l’événement qui se produit (ici, la création d’un compte) pour écrire la logique nécessaire à la création d’une tâche. La lecture du code est donc nécessaire pour en saisir le but.

C’est ici que le principe de l’inversion du contrôle entre en jeu. Quand un compte est créé, je veux que la tâche soit créée aussi, sans que je n’aie à savoir comment. L’idée est de faire abstraction des détails d’implémentation, qui devraient dépendre du cas d’utilisation (et non l’inverse). Ainsi, le code reste axé sur le but à atteindre.

Avant toute adaptation, le code ressemblerait à ce qui suit; nous devons donc le lire pour en comprendre le but :

Avant

Avant

 

Passer des détails de mise en œuvre à une approche par cas d’utilisation

La première étape de linversion de contrôle consiste à transférer les détails de mise en œuvre dans une autre classe. On peut alors la tester sans utiliser Dynamics (un test unitaire au lieu dun test dintégration). 

Voici le code après avoir transféré la logique dans une autre classe : 

Après le transfert dans une autre classe - 3 fichiers

Après le transfert dans une autre classe – 3 fichiers

 

Lobjectif du plugin devient clair. Linterface est illustrée ci-dessous, et la classe concrète CreateTaskOnAccountCreationCommand la met en œuvre essentiellement de la même manière quauparavant.  

 

Intégratiode Ninject de manière prise en charge dans un projet de plugin de Dynamics365 

Jai déjà travaillé sur un projet qui ne comportait pas dinjection de dépendance. Laissez-moi vous dire quil devient fastidieux de créer les objets quand le constructeur comporte une douzaine de paramètres. Cest là que brille linjection de dépendance. 

Pour supprimer la dépendance à légard des détails de mise en œuvre, il faut demander à Ninject de créer une instance de la classe. Cette inversion de contrôle se fait généralement en utilisant Nuget pour importer sa bibliothèque. Par contrecest impossible dans Dynamics365, qui nd prend pas en charge la fusion de plusieurs bibliothèquesUne solution consiste à télécharger tout le code source de Ninject et à copier tous les fichiers sources (*.cs) dans notre projet (la licence de Ninject  le permet). 

Pour ne plus dépendre des détails dimplémentation, nous commençons à utiliser Ninject. Donc, le plugin ne saura plus comment les détails sont implémentésPourquoi procéder ainsi? Pour lavantage de ne pas avoir à connaître les détails de limplémentation. Ainsi, nous pourrions les remplacer par une autre implémentation et la tester indépendamment de Dynamics 365. 

 

Introduction de linversion de contrôle avec Ninject 

Il faut dabord ajouter le résolveur de dépendances et Ninject, puis lier les interfaces à leurs implémentations. Nous ajoutons donc une référence à Ninject .  

 

Créer une instance de classe avec Ninject 

De cette façon, le plugin ignore limplémentation de la création de tâche, mais à la lecture du code, nous en comprenons le but. L’inversion de contrôle est effectuée par Ninject:

Inversion de contrôle

 

Donc, au moment dexécuter les détails (dans notre cas, créer une tâche lors de la création dun compte), Ninject crée une instance de la classe CreateTaskOnAccountCreationCommand, ce qui relie linterface qui me dit que je veux exécuter la commande avec les détails dimplémentationIl est donc possible de remplacer une implémentation par une autre en changeant uniquement le DependencyResolver. 

Enfin, linjection de dépendance signifie que Ninject crée pour nous les objets avec tous leurs membres. Si ce nétait pas le cas, la tâche serait fastidieuse. Par exemple, nous pourrions fractionner le code de sorte que la création de tâche soit une classe et que lorchestrateur qui linvoque lors de la création dun compte soit une autre classeCertes, on pourrait dire que cest exagéré pour un besoin aussi simple, mais pour des projets plus complexes comportant de nombreuses dépendances, lapproche devient intéressante. Voici l’orchestrateur : 

 

Cependant, la commande requiert deux autres paramètres lorsquelle est instanciée : 

 

Créer une instance de classe et passer dans le OrganizationService depuis le plugin 

Sans Ninject et linversion de contrôle, il faudrait créer tous les objets et fournir les paramètres nécessaires à tous les constructeurs. Plutôt, nous disons simplement à Ninject de lier les interfaces aux classes qui les implémentent et parfois de spécifier des paramètres, par exemple pour la commande suivante : 

 

Lorsque Ninject crée lobjet CreateTaskOnAccreationCreationCommand, il choisit le constructeur le plus complexe et crée les objets nécessaires. Dans notre cas, il crée une instance de lobjet CreateTaskCommand et la transmet au constructeur CreateTaskOnAccreationCreationCommand. Pour créer lobjet CreateTaskCommand, il va créer une instance de lobjet TaskFactory et la passer au constructeur CreateTaskCommand ainsi quà linstance IOrganizationService que le plugin a fournie lors de son exécution. 

 

Le point sur lapproche 

Enfin, la dissimulation des détails dimplémentation rend le code plus facile à lire et à comprendre. On se détache de la mise en place de plugins concrets. Cette méthode facilite la substitution des détails dimplémentation et permet de tout faire en un seul endroit. Elle facilite également les tests de logique dans chacune des classes, car nous pouvons mettre en œuvre une interface qui teste des fragments de code sans tester lensemble.  

Pour récapituler, voici les avantages de la méthode proposée : 

  • axée sur les cas d’utilisation; 
  • code clair et facile à comprendre, à entretenir et à tester; 
  • couplage faible pour pouvoir remplacer des parties du code plus facilement. 

Bref, il va sans dire que la méthode sillustre dans les projets denvergure et quelle ne vaut pas leffort dans un petit projet comme celui pris en exempleCependant, cet exemple a été utilisé pour illustrer les principes qui peuvent être appliqués dans un grand projet. 


Cet article est une initiative de notre expert Jean-François Fortin. 

 

À lire aussi

Comment connecter Dynamics 365 à Azure pour enregistrer les erreurs?

Vous aimeriez en savoir plus?

Notre équipe peut vous accompagner avec des conseils personnalisés, des formations ou de nouvelles solutions adaptées à vos besoins. Optimisez l’utilisation de vos technologies et vos processus quotidiens : contactez l’un(e) de nos expert(e)s.

Pour rester au fait des dernières nouvelles, suivez-nous sur LinkedIn et sur notre chaîne Youtube!