Procédure pas à pas : Incorporer des types d’assemblys managés dans Visual Studio
Si vous incorporez des informations de type d’un assembly managé avec nom fort, vous pouvez coupler faiblement des types dans une application pour obtenir une indépendance de version. Cela signifie que votre programme peut être écrit pour utiliser des types de toute version d’une bibliothèque managée sans qu’il soit nécessaire d’effectuer de recompilation pour chaque nouvelle version.
L’incorporation de type est fréquemment utilisée avec COM Interop, par exemple pour une application qui utilise des objets Automation de Microsoft Office. L’incorporation des informations de type permet à la même build d’un programme de fonctionner avec différentes versions de Microsoft Office sur plusieurs ordinateurs. Toutefois, vous pouvez également utiliser l’incorporation de type avec une solution totalement managée.
Après avoir spécifié les interfaces publiques qui peuvent être incorporées, vous créez des classes runtime qui implémentent ces interfaces. Un programme client peut incorporer les informations de type pour les interfaces au moment de la conception en référençant l’assembly qui contient les interfaces publiques et en définissant à propriété Embed Interop Types
de la référence sur True
. Le programme client peut ensuite charger des instances des objets d’exécution possédant le même type que ces interfaces. Cela revient à utiliser le compilateur de ligne de commande et à référencer l’assembly à l’aide de l’option de compilateur EmbedInteropTypes.
Si vous créez une version de votre assembly runtime avec nom fort, le programme client n’a pas besoin d’être recompilé. Le programme client continue d’utiliser la version de l’assembly runtime disponible avec les informations de type incorporées pour les interfaces publiques.
Lors de cette procédure pas à pas, vous allez effectuer les opérations suivantes :
- Créer un assembly avec nom fort doté d’une interface publique contenant des informations de type pouvant être incorporées.
- Créer un assembly runtime avec nom fort qui implémente cette interface publique.
- Créer un programme client qui incorpore les informations de type de l’interface publique et crée une instance de la classe à partir de l’assembly runtime.
- Modifier et régénérer l’assembly runtime.
- Exécuter le programme client pour constater qu’il utilise la nouvelle version de l’assembly runtime sans qu’il soit nécessaire de le recompiler.
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.
Conditions et limitations
Vous pouvez incorporer des informations de type à partir d’un assembly dans les conditions suivantes :
- L’assembly expose au moins une interface publique.
- Les interfaces incorporées sont annotées avec des attributs
ComImport
etGuid
comportant des GUID uniques. - L’assembly est annoté avec l’attribut
ImportedFromTypeLib
ou l’attributPrimaryInteropAssembly
et un attributGuid
au niveau de l’assembly. Les modèles de projet Visual C# et Visual Basic incluent un attribut au niveau de l’assemblyGuid
par défaut.
Étant donné que la fonction principale de l’incorporation de type est de prendre en charge les assemblys COM Interop, les limitations suivantes s’appliquent quand vous incorporez des informations de type dans une solution totalement managée :
- Seuls les attributs spécifiques à COM Interop sont incorporés. Les autres attributs sont ignorés.
- Si un type utilise des paramètres génériques et que le type du paramètre générique est un type incorporé, ce type ne peut pas être utilisé au-delà de la limite de l’assembly. Les exemples de passage de la limite de l’assembly incluent l’appel d’une méthode à partir d’un autre assembly ou la dérivation d’un type à partir d’un type défini dans un autre assembly.
- Les constantes ne sont pas incorporées.
- La classe System.Collections.Generic.Dictionary<TKey,TValue> ne prend pas en charge un type incorporé comme clé. Vous pouvez implémenter votre propre type de dictionnaire pour prendre en charge un type incorporé comme clé.
Créer une interface
La première étape consiste à créer l’assembly d’interface d’équivalence de type.
Dans Visual Studio, sélectionnez Fichier>Nouveau>Projet.
Dans la boîte de dialogue Créer un projet, tapez bibliothèque de classes dans la zone Rechercher des modèles. Sélectionnez le modèle Bibliothèque de classes (.NET Framework) C# ou Visual Basic dans la liste, puis sélectionnez Suivant.
Dans la boîte de dialogue Configurer votre nouveau projet, sous Nom du projet, tapez TypeEquivalenceInterface, puis sélectionnez Créer. Le nouveau projet est créé.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le fichier Class1.cs ou Class1.vb, sélectionnez Renommer, puis renommez le fichier en remplaçant Class1 par ISampleInterface. Répondez Oui à l’invite afin de renommer également la classe en
ISampleInterface
. Cette classe représente l’interface publique pour la classe.Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceInterface, puis sélectionnez Propriétés.
Sélectionnez Générer dans le volet gauche de l’écran Propriétés, puis définissez le chemin de sortie sur un emplacement de votre ordinateur, comme C:\TypeEquivalenceSample. Vous utilisez le même emplacement dans toute cette procédure pas à pas.
Sélectionnez Générer>Nom fort dans le volet gauche de l’écran Propriétés, puis cochez la case Signer l’assembly. Dans le fichier de clé à nom fort, sélectionnez Parcourir.
Accédez à et sélectionnez le fichier key.snk que vous avez créé dans le projet TypeEquivalenceInterface, puis sélectionnez OK. Pour plus d’informations, consultez Créer une paire de clés publique/privée.
Ouvrez le fichier de classe ISampleInterface dans l’éditeur de code et remplacez le contenu par le code suivant pour créer l’interface
ISampleInterface
:using System; using System.Runtime.InteropServices; namespace TypeEquivalenceInterface { [ComImport] [Guid("8DA56996-A151-4136-B474-32784559F6DF")] public interface ISampleInterface { void GetUserInput(); string UserInput { get; } } }
Imports System.Runtime.InteropServices <ComImport()> <Guid("8DA56996-A151-4136-B474-32784559F6DF")> Public Interface ISampleInterface Sub GetUserInput() ReadOnly Property UserInput As String End Interface
Dans le menu Outils, sélectionnez Créer un GUID, puis dans la boîte de dialogue Créer un GUID, sélectionnez Format du registre. Sélectionnez Copier, puis Quitter.
Dans l’attribut
Guid
de votre code, remplacez l’exemple de GUID par le GUID que vous avez copié, puis supprimez les accolades ({ }).Dans l’Explorateur de solutions, développez le dossier Propriétés et sélectionnez le fichier AssemblyInfo.cs ou AssemblyInfo.vb. Dans l’éditeur de code, ajoutez l’attribut suivant au fichier :
[assembly: ImportedFromTypeLib("")]
<Assembly: ImportedFromTypeLib("")>
Sélectionnez Fichier>Enregistrer tout ou appuyez sur Ctrl+Maj+S pour enregistrer les fichiers et le projet.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceInterface, puis sélectionnez Générer. Le fichier DLL de bibliothèque de classes est compilé et enregistré dans le chemin de sortie de la génération spécifié, par exemple C:\TypeEquivalenceSample.
Créer une classe runtime
Créez ensuite la classe runtime d’équivalence de type.
Dans Visual Studio, sélectionnez Fichier>Nouveau>Projet.
Dans la boîte de dialogue Créer un projet, tapez bibliothèque de classes dans la zone Rechercher des modèles. Sélectionnez le modèle Bibliothèque de classes (.NET Framework) C# ou Visual Basic dans la liste, puis sélectionnez Suivant.
Dans la boîte de dialogue Configurer votre nouveau projet, sous Nom du projet, tapez TypeEquivalenceRuntime, puis sélectionnez Créer. Le nouveau projet est créé.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le fichier Class1.cs ou Class1.vb, sélectionnez Renommer, puis renommez le fichier en remplaçant Class1 par SampleClass. Répondez Oui à l’invite afin de renommer également la classe en
SampleClass
. Cette classe implémente l’interfaceISampleInterface
.Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceInterface et sélectionnez Propriétés.
Sélectionnez Générer dans le volet gauche de l’écran Propriétés, puis définissez le chemin de sortie sur l’emplacement que vous avez utilisé pour le projet TypeEquivalenceInterface, par exemple C:\TypeEquivalenceSample.
Sélectionnez Générer>Nom fort dans le volet gauche de l’écran Propriétés, puis cochez la case Signer l’assembly. Dans le fichier de clé à nom fort, sélectionnez Parcourir.
Accédez à et sélectionnez le fichier key.snk que vous avez créé dans le projet TypeEquivalenceInterface, puis sélectionnez OK. Pour plus d’informations, consultez Créer une paire de clés publique/privée.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceRuntime et sélectionnez Ajouter>Référence.
Dans la boîte de dialogue Gestionnaire de références, sélectionnez Parcourir et accédez au dossier du chemin de sortie. Sélectionnez le fichier TypeEquivalenceInterface.dll, sélectionnez Ajouter, puis sélectionnez OK.
Dans l’Explorateur de solutions, développez le dossier Références et sélectionnez la référence TypeEquivalenceInterface. Dans le volet Propriétés, définissez Version spécifique sur False le cas échéant.
Ouvrez le fichier de classe SampleClass dans l’éditeur de code et remplacez le contenu par le code suivant pour créer la classe
SampleClass
:using System; using TypeEquivalenceInterface; namespace TypeEquivalenceRuntime { public class SampleClass : ISampleInterface { private string p_UserInput; public string UserInput { get { return p_UserInput; } } public void GetUserInput() { Console.WriteLine("Please enter a value:"); p_UserInput = Console.ReadLine(); } } }
Imports TypeEquivalenceInterface Public Class SampleClass Implements ISampleInterface Private p_UserInput As String Public ReadOnly Property UserInput() As String Implements ISampleInterface.UserInput Get Return p_UserInput End Get End Property Public Sub GetUserInput() Implements ISampleInterface.GetUserInput Console.WriteLine("Please enter a value:") p_UserInput = Console.ReadLine() End Sub End Class
Sélectionnez Fichier>Enregistrer tout ou appuyez sur Ctrl+Maj+S pour enregistrer les fichiers et le projet.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceRuntime, puis sélectionnez Générer. Le fichier DLL de bibliothèque de classes est compilée et enregistrée dans le chemin de sortie de la génération.
Créer un projet client
Enfin, créez un programme client d’équivalence de type qui référence l’assembly d’interface.
Dans Visual Studio, sélectionnez Fichier>Nouveau>Projet.
Dans la boîte de dialogue Créer un projet, tapez console dans la zone Rechercher des modèles. Sélectionnez le modèle Application console (.NET Framework) C# ou Visual Basic dans la liste, puis sélectionnez Suivant.
Dans la boîte de dialogue Configurer votre nouveau projet, sous Nom du projet, tapez TypeEquivalenceClient, puis sélectionnez Créer. Le nouveau projet est créé.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceClient et sélectionnez Propriétés.
Sélectionnez Générer dans le volet gauche de l’écran Propriétés, puis définissez le chemin de sortie sur l’emplacement que vous avez utilisé pour le projet TypeEquivalenceInterface, par exemple C:\TypeEquivalenceSample.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceClient et sélectionnez Ajouter>Référence.
Dans la boîte de dialogue Gestionnaire de références, si le fichier TypeEquivalenceInterface.dll est déjà répertorié, sélectionnez-le. Si ce n’est pas le cas, sélectionnez Parcourir, accédez au dossier du chemin de sortie, sélectionnez le fichier TypeEquivalenceInterface.dll (et non TypeEquivalenceRuntime.dll), puis sélectionnez Ajouter. Sélectionnez OK.
Dans l’Explorateur de solutions, développez le dossier Références et sélectionnez la référence TypeEquivalenceInterface. Dans le volet Propriétés, définissez Incorporer les types d’interopérabilité sur True.
Ouvrez le fichier Program.cs ou Module1.vb dans l’éditeur de code, puis remplacez son contenu par le code suivant pour créer le programme client :
using System; using System.Reflection; using TypeEquivalenceInterface; namespace TypeEquivalenceClient { class Program { static void Main(string[] args) { Assembly sampleAssembly = Assembly.Load("TypeEquivalenceRuntime"); ISampleInterface sampleClass = (ISampleInterface)sampleAssembly.CreateInstance("TypeEquivalenceRuntime.SampleClass"); sampleClass.GetUserInput(); Console.WriteLine(sampleClass.UserInput); Console.WriteLine(sampleAssembly.GetName().Version.ToString()); Console.ReadLine(); } } }
Imports System.Reflection Imports TypeEquivalenceInterface Module Module1 Sub Main() Dim sampleAssembly = Assembly.Load("TypeEquivalenceRuntime") Dim sampleClass As ISampleInterface = CType( _ sampleAssembly.CreateInstance("TypeEquivalenceRuntime.SampleClass"), ISampleInterface) sampleClass.GetUserInput() Console.WriteLine(sampleClass.UserInput) Console.WriteLine(sampleAssembly.GetName().Version) Console.ReadLine() End Sub End Module
Sélectionnez Fichier>Enregistrer tout ou appuyez sur Ctrl+Maj+S pour enregistrer les fichiers et le projet.
Appuyez sur Ctrl+F5 pour générer et exécuter le programme. Notez que la sortie de la console retourne la version de l’assembly 1.0.0.0.
Modifier l’interface
Modifiez ensuite l’assembly d’interface et modifiez sa version.
Dans Visual Studio, sélectionnez Fichier>Ouvrir>Projet/Solution et ouvrez le projet TypeEquivalenceInterface.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceInterface et sélectionnez Propriétés.
Sélectionnez Application dans le volet gauche de l’écran Propriétés, puis sélectionnez Informations de l’assembly.
Dans la boîte de dialogue Informations de l’assembly, remplacez les valeurs Version de l’assembly et Version de fichier par 2.0.0.0, puis sélectionnez OK.
Ouvrez le fichier SampleInterface.cs ou SampleInterface.vb, puis ajoutez la ligne de code suivante à l’interface
ISampleInterface
:DateTime GetDate();
Function GetDate() As Date
Sélectionnez Fichier>Enregistrer tout ou appuyez sur Ctrl+Maj+S pour enregistrer les fichiers et le projet.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceInterface, puis sélectionnez Générer. Une nouvelle version du fichier DLL de bibliothèque de classes est compilée et enregistrée dans le chemin de sortie de build.
Modifier la classe runtime
Modifiez également la classe runtime et mettez à jour sa version.
Dans Visual Studio, sélectionnez Fichier>Ouvrir>Projet/Solution, puis ouvrez le projet TypeEquivalenceRuntime.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceRuntime et sélectionnez Propriétés.
Sélectionnez Application dans le volet gauche de l’écran Propriétés, puis sélectionnez Informations de l’assembly.
Dans la boîte de dialogue Informations de l’assembly, remplacez les valeurs Version de l’assembly et Version de fichier par 2.0.0.0, puis sélectionnez OK.
Ajoutez le fichier SampleClass.cs ou SampleClass.vb et ajoutez le code suivant à la classe
SampleClass
:public DateTime GetDate() { return DateTime.Now; }
Public Function GetDate() As DateTime Implements ISampleInterface.GetDate Return Now End Function
Sélectionnez Fichier>Enregistrer tout ou appuyez sur Ctrl+Maj+S pour enregistrer les fichiers et le projet.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet TypeEquivalenceRuntime, puis sélectionnez Générer. Une nouvelle version du fichier DLL de bibliothèque de classes est compilée et enregistrée dans le chemin de sortie de build.
Exécuter le programme client mis à jour
Accédez à l’emplacement du dossier de sortie de build et exécutez TypeEquivalenceClient.exe. Notez que la sortie de console reflète désormais la nouvelle version de l’assembly TypeEquivalenceRuntime
, 2.0.0.0, sans que le programme soit recompilé.