Procédure pas-à-pas : création et utilisation d'objets dynamiques en Visual Basic
Les objets dynamiques exposent des membres tels que les propriétés et les méthodes au moment de l’exécution et non lors de la compilation. Cela vous permet de créer des objets utilisables avec des structures qui ne correspondent pas à un type ou un format statique. Par exemple, vous pouvez utiliser un objet dynamique pour référencer le modèle DOM (Document Object Model) HTML, qui peut contenir n’importe quelle combinaison d’attributs et d’éléments de balisage HTML valides. Étant donné que chaque document HTML est unique, les membres d’un document HTML particulier sont déterminés au moment de l’exécution. L’une des méthodes courantes pour référencer un attribut d’un élément HTML consiste à passer le nom de l’attribut à la méthode GetProperty
de l’élément. Pour référencer l’attribut id
de l’élément HTML <div id="Div1">
, vous obtenez d’abord une référence à l’élément <div>
, puis utilisez divElement.GetProperty("id")
. Si vous utilisez un objet dynamique, vous pouvez référencer l’attribut id
comme divElement.id
.
Les objets dynamiques permettent également d’accéder facilement aux langages dynamiques comme IronPython et IronRuby. Vous pouvez utiliser un objet dynamique pour faire référence à un script dynamique qui est interprété au moment de l’exécution.
Vous référencez un objet dynamique à l’aide de la liaison tardive. Vous spécifiez le type d’un objet à liaison tardive comme Object
. Pour plus d'informations, consultez [Liaison anticipée et liaison tardive.
Vous pouvez créer des objets dynamiques personnalisés en utilisant les classes contenues dans l’espace de noms System.Dynamic. Par exemple, vous pouvez créer un ExpandoObject et spécifier les membres de cet objet au moment de l’exécution. Vous pouvez aussi créer votre propre type qui hérite de la classe DynamicObject. Vous pouvez ensuite substituer les membres de la classe DynamicObject pour fournir des fonctionnalités dynamiques au moment de l’exécution.
Cet article contient deux procédures pas à pas indépendantes :
Créer un objet personnalisé qui expose dynamiquement le contenu d’un fichier texte comme propriétés d’un objet.
Créer un projet qui utilise une bibliothèque
IronPython
.
Vous pouvez choisir l’une ou l’autre, et si vous faites les deux, l’ordre n’a pas d’importance.
Prérequis
- Visual Studio 2019 version 16.9 ou ultérieure avec la charge de travail de développement de bureau .NET installée. Le Kit de développement logiciel (SDK) .NET 5 est installé automatiquement lorsque vous sélectionnez cette charge de travail.
Notes
Il est possible que pour certains des éléments de l'interface utilisateur de Visual Studio, votre ordinateur affiche des noms ou des emplacements différents de ceux indiqués dans les instructions suivantes. L'édition de Visual Studio dont vous disposez et les paramètres que vous utilisez déterminent ces éléments. Pour plus d’informations, consultez Personnalisation de l’IDE.
- Pour la deuxième procédure pas à pas, installez IronPython pour .NET. Accédez à la page de téléchargement pour obtenir la version la plus récente.
Créer un objet dynamique personnalisé
La première procédure pas à pas définit un objet dynamique personnalisé qui recherche le contenu d’un fichier texte. Une propriété dynamique spécifie le texte à rechercher. Par exemple, si le code appelant spécifie dynamicFile.Sample
, la classe dynamique retourne une liste générique de chaînes qui contient toutes les lignes du fichier qui commencent par « Sample ». La recherche respecte la casse. La classe dynamique prend également en charge deux arguments facultatifs. Le premier argument est une valeur enum de l’option de recherche qui spécifie que la classe dynamique doit rechercher des correspondances en début de ligne, en fin de ligne, ou n’importe où dans la ligne. Le deuxième argument spécifie que la classe dynamique doit supprimer des espaces à gauche et à droite dans chaque ligne avant d’effectuer la recherche. Par exemple, si le code appelant spécifie dynamicFile.Sample(StringSearchOption.Contains)
, la classe dynamique recherche le terme « Sample » n’importe où dans une ligne. Si le code appelant spécifie dynamicFile.Sample(StringSearchOption.StartsWith, false)
, la classe dynamique recherche le terme « Sample » au début de chaque ligne et ne supprime ni les espaces à droite, ni les espaces à gauche. Le comportement par défaut de la classe dynamique consiste à rechercher une correspondance au début de chaque ligne et à supprimer les espaces à gauche et à droite.
Pour créer une classe dynamique personnalisée
Démarrez Visual Studio.
Sélectionnez Créer un projet.
Dans la boîte de dialogue Créer un projet, sélectionnez Visual Basic, sélectionnez Application console, puis sélectionnez Suivant.
Dans la boîte de dialogue Configurer votre nouveau projet, entrez
DynamicSample
pour le Nom de projet, puis sélectionnez Suivant.Dans la boîte de dialogue Informations supplémentaires , sélectionnez .NET 5.0 (Actif) pour le Framework cible, puis sélectionnez Créer.
Le nouveau projet est créé.
Dans l’Explorateur de solutionsfaites un clic droit sur le projet DynamicSample, puis sélectionnez Ajouter>une Classe. Dans la zone Nom, tapez
ReadOnlyFile
, puis sélectionnez Ajouter.Un nouveau fichier contenant la classe ReadOnlyFile est ajouté.
En haut du fichier ReadOnlyFile.cs ou ReadOnlyFile.vb, ajoutez le code suivant pour importer les espaces de noms System.IO et System.Dynamic.
Imports System.IO Imports System.Dynamic
L’objet dynamique personnalisé utilise un enum pour déterminer les critères de recherche. Avant l’instruction de classe, ajoutez la définition d’enum suivante.
Public Enum StringSearchOption StartsWith Contains EndsWith End Enum
Mettez à jour l’instruction de classe de façon à hériter de la classe
DynamicObject
, comme indiqué dans l’exemple de code suivant.Public Class ReadOnlyFile Inherits DynamicObject
Ajoutez le code suivant à la classe
ReadOnlyFile
afin de définir un champ privé pour le chemin du fichier et un constructeur pour la classeReadOnlyFile
.' Store the path to the file and the initial line count value. Private p_filePath As String ' Public constructor. Verify that file exists and store the path in ' the private variable. Public Sub New(ByVal filePath As String) If Not File.Exists(filePath) Then Throw New Exception("File path does not exist.") End If p_filePath = filePath End Sub
Ajoutez la méthode
GetPropertyValue
suivante à la classeReadOnlyFile
. La méthodeGetPropertyValue
prend les critères de recherche comme paramètre d’entrée et retourne les lignes d’un fichier texte qui correspondent aux critères de recherche. Les méthodes dynamiques fournies par la classeReadOnlyFile
appellent la méthodeGetPropertyValue
pour récupérer leurs résultats respectifs.Public Function GetPropertyValue(ByVal propertyName As String, Optional ByVal StringSearchOption As StringSearchOption = StringSearchOption.StartsWith, Optional ByVal trimSpaces As Boolean = True) As List(Of String) Dim sr As StreamReader = Nothing Dim results As New List(Of String) Dim line = "" Dim testLine = "" Try sr = New StreamReader(p_filePath) While Not sr.EndOfStream line = sr.ReadLine() ' Perform a case-insensitive search by using the specified search options. testLine = UCase(line) If trimSpaces Then testLine = Trim(testLine) Select Case StringSearchOption Case StringSearchOption.StartsWith If testLine.StartsWith(UCase(propertyName)) Then results.Add(line) Case StringSearchOption.Contains If testLine.Contains(UCase(propertyName)) Then results.Add(line) Case StringSearchOption.EndsWith If testLine.EndsWith(UCase(propertyName)) Then results.Add(line) End Select End While Catch ' Trap any exception that occurs in reading the file and return Nothing. results = Nothing Finally If sr IsNot Nothing Then sr.Close() End Try Return results End Function
Après la méthode
GetPropertyValue
, ajoutez le code suivant pour substituer la méthode TryGetMember de la classe DynamicObject. La méthode TryGetMember est appelée quand un membre d’une classe dynamique est demandé et qu’aucun argument n’est spécifié. L’argumentbinder
contient les informations relatives au membre référencé et l’argumentresult
référence le résultat retourné pour le membre spécifié. La méthode TryGetMember retourne une valeur booléenne qui retournetrue
si le membre demandé existe ; sinon, elle retourne la valeurfalse
.' Implement the TryGetMember method of the DynamicObject class for dynamic member calls. Public Overrides Function TryGetMember(ByVal binder As GetMemberBinder, ByRef result As Object) As Boolean result = GetPropertyValue(binder.Name) Return If(result Is Nothing, False, True) End Function
Après la méthode
TryGetMember
, ajoutez le code suivant pour substituer la méthode TryInvokeMember de la classe DynamicObject. La méthode TryInvokeMember est appelée quand un membre d’une classe dynamique est demandé avec des arguments. L’argumentbinder
contient les informations relatives au membre référencé et l’argumentresult
référence le résultat retourné pour le membre spécifié. L’argumentargs
contient un tableau des arguments passés au membre. La méthode TryInvokeMember retourne une valeur booléenne qui retournetrue
si le membre demandé existe ; sinon, elle retourne la valeurfalse
.La version personnalisée de la méthode
TryInvokeMember
s’attend à ce que le premier argument soit une valeur de l’enumStringSearchOption
que vous avez défini dans une étape précédente. La méthodeTryInvokeMember
s’attend à ce que le deuxième argument soit une valeur booléenne. Si l’un des arguments ou les deux arguments sont des valeurs valides, ils sont passés à la méthodeGetPropertyValue
pour récupérer les résultats.' Implement the TryInvokeMember method of the DynamicObject class for ' dynamic member calls that have arguments. Public Overrides Function TryInvokeMember(ByVal binder As InvokeMemberBinder, ByVal args() As Object, ByRef result As Object) As Boolean Dim StringSearchOption As StringSearchOption = StringSearchOption.StartsWith Dim trimSpaces = True Try If args.Length > 0 Then StringSearchOption = CType(args(0), StringSearchOption) Catch Throw New ArgumentException("StringSearchOption argument must be a StringSearchOption enum value.") End Try Try If args.Length > 1 Then trimSpaces = CType(args(1), Boolean) Catch Throw New ArgumentException("trimSpaces argument must be a Boolean value.") End Try result = GetPropertyValue(binder.Name, StringSearchOption, trimSpaces) Return If(result Is Nothing, False, True) End Function
Enregistrez et fermez le fichier.
Pour créer un exemple de fichier texte
Dans l’Explorateur de solutionsfaites un clic droit sur le projet DynamicSample, puis sélectionnez Ajouter>un Nouvel élément. Dans le volet Modèles installés, sélectionnez Général, puis sélectionnez le modèle Fichier texte. Conservez le nom par défaut de TextFile1.txt dans la zone Nom, puis cliquez sur Ajouter. Un nouveau fichier texte est ajouté au projet.
Copiez le texte suivant dans le fichier TextFile1.txt.
List of customers and suppliers Supplier: Lucerne Publishing (https://www.lucernepublishing.com/) Customer: Preston, Chris Customer: Hines, Patrick Customer: Cameron, Maria Supplier: Graphic Design Institute (https://www.graphicdesigninstitute.com/) Supplier: Fabrikam, Inc. (https://www.fabrikam.com/) Customer: Seubert, Roxanne Supplier: Proseware, Inc. (http://www.proseware.com/) Customer: Adolphi, Stephan Customer: Koch, Paul
Enregistrez et fermez le fichier.
Pour créer un exemple d’application qui utilise l’objet dynamique personnalisé
Dans l'Explorateur de solutions, double-cliquez sur le fichier Program.vb.
Ajoutez le code suivant à la procédure
Main
pour créer une instance de la classeReadOnlyFile
pour le fichier TextFile1.txt. Le code utilise la liaison tardive pour appeler des membres dynamiques et récupérer des lignes de texte qui contiennent la chaîne « Customer ».Dim rFile As Object = New ReadOnlyFile("..\..\..\TextFile1.txt") For Each line In rFile.Customer Console.WriteLine(line) Next Console.WriteLine("----------------------------") For Each line In rFile.Customer(StringSearchOption.Contains, True) Console.WriteLine(line) Next
Enregistrez le fichier et appuyez sur Ctrl+F5 pour générer et exécuter l’application.
Appeler une bibliothèque de langage dynamique
La procédure pas à pas suivante crée un projet qui accède à une bibliothèque écrite dans le langage dynamique IronPython.
Pour créer une classe dynamique personnalisée
Dans Visual Studio, sélectionnez Fichier>Nouveau>Projet.
Dans la boîte de dialogue Créer un projet, sélectionnez Visual Basic, sélectionnez Application console, puis sélectionnez Suivant.
Dans la boîte de dialogue Configurer votre nouveau projet, entrez
DynamicIronPythonSample
pour le Nom de projet, puis sélectionnez Suivant.Dans la boîte de dialogue Informations supplémentaires , sélectionnez .NET 5.0 (Actif) pour le Framework cible, puis sélectionnez Créer.
Le nouveau projet est créé.
Installez le package NuGet IronPython.
Modifiez le fichier Program.vb.
En haut du fichier, ajoutez le code suivant pour importer les espaces de noms
Microsoft.Scripting.Hosting
etIronPython.Hosting
à partir des bibliothèques IronPython et de l’espace de nomsSystem.Linq
.Imports Microsoft.Scripting.Hosting Imports IronPython.Hosting Imports System.Linq
Dans la méthode Main, ajoutez le code suivant pour créer un objet
Microsoft.Scripting.Hosting.ScriptRuntime
pour héberger les bibliothèques IronPython. L’objetScriptRuntime
charge le module de bibliothèque IronPython random.py.' Set the current directory to the IronPython libraries. System.IO.Directory.SetCurrentDirectory( Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) & "\IronPython 2.7\Lib") ' Create an instance of the random.py IronPython library. Console.WriteLine("Loading random.py") Dim py = Python.CreateRuntime() Dim random As Object = py.UseFile("random.py") Console.WriteLine("random.py loaded.")
Une fois que le code a chargé le module random.py, ajoutez le code suivant pour créer un tableau d’entiers. Le tableau est passé à la méthode
shuffle
du module random.py, qui trie aléatoirement les valeurs dans le tableau.' Initialize an enumerable set of integers. Dim items = Enumerable.Range(1, 7).ToArray() ' Randomly shuffle the array of integers by using IronPython. For i = 0 To 4 random.shuffle(items) For Each item In items Console.WriteLine(item) Next Console.WriteLine("-------------------") Next
Enregistrez le fichier et appuyez sur Ctrl+F5 pour générer et exécuter l’application.