Procédure pas à pas : incorporation de types provenant d'assemblys managés (C# et Visual Basic)
Si vous incorporez les 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. Autrement dit, votre programme peut être écrit de façon à ce qu'il utilise des types de plusieurs versions d'une bibliothèque managée sans que vous ayez à effectuer de recompilation pour chaque 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 version d'un programme de fonctionner avec différentes versions de Microsoft Office sur de multiples ordinateurs. Toutefois, vous pouvez également utiliser l'incorporation de type avec une solution totalement managée.
Les informations de type peuvent être incorporées à partir d'un assembly doté des caractéristiques suivantes :
L'assembly expose une interface publique au moins.
Les interfaces incorporées sont annotées avec un attribut ComImport et un attribut Guid (et un GUID unique).
L'assembly est annoté avec l'attribut ImportedFromTypeLib ou l'attribut PrimaryInteropAssembly et un attribut Guid au niveau de l'assembly. (Par défaut, les modèles de projet Visual Basic et Visual C# incluent un attribut Guid au niveau de l'assembly.)
Après avoir spécifié les interfaces publiques qui peuvent être incorporées, vous pouvez créer des classes d'exécution qui implémentent ces interfaces. Un programme client peut ensuite incorporer les informations de type pour ces interfaces au moment de la conception en référençant l'assembly qui contient les interfaces publiques et en affectant à la propriété Embed Interop Types de la référence la valeur True. Cela revient à utiliser le compilateur de ligne de commande et à référencer l'assembly à l'aide de l'option de compilateur /link. Le programme client peut ensuite charger des instances de vos objets d'exécution possédant le même type que ces interfaces. Si vous créez une nouvelle version de votre assembly de runtime avec nom fort, le programme client n'a pas besoin d'être recompilé avec l'assembly de runtime mis à jour. En fait, le programme client continue à utiliser la version de l'assembly de runtime disponible avec les informations de type incorporées pour les interfaces publiques.
Étant donné que la fonction principale de l'incorporation de type est de prendre en charge l'incorporation d'informations de type à partir d'assemblys COM interop, les limitations suivantes s'appliquent lorsque 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 Dictionary 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é.
Dans cette procédure pas à pas, vous exécuterez les étapes suivantes :
Créer un assembly avec nom fort doté d'une interface publique contenant des informations de type qui peuvent être incorporées.
Créer un assembly de 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 de runtime.
Modifier et régénérer l'assembly de runtime.
Exécuter le programme client pour constater que la nouvelle version de l'assembly de runtime est utilisée sans devoir recompiler le programme client.
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, voir Paramètres Visual Studio.
Création d'une interface
Pour créer le projet d'interface d'équivalence des types
Dans Visual Studio, dans le menu Fichier, pointez sur Nouveau, puis cliquez sur Projet.
Dans la boîte de dialogue Nouveau projet, dans le volet Types de projets, vérifiez que Windows est sélectionné. Sélectionnez Bibliothèque de classes dans le volet Modèles. Dans la zone Nom, tapez TypeEquivalenceInterface, puis cliquez sur OK. Le nouveau projet est créé.
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le fichier Class1.vb ou Class1.cs, puis cliquez sur Renommer. Renommez le fichier en ISampleInterface.vb ou ISampleInterface.cs et appuyez sur ENTRÉE. Lorsque vous renommez le fichier, la classe sera également renommée en ISampleInterface. Cette classe représentera l'interface publique pour la classe.
Cliquez avec le bouton droit sur le projet TypeEquivalenceInterface, puis cliquez sur Propriétés. Cliquez sur l'onglet Compiler dans Visual Basic ou sur l'onglet Générer dans Visual C#. Affectez au chemin de sortie un emplacement valide sur votre ordinateur de développement, tel que C:\TypeEquivalenceSample. Cet emplacement sera également utilisé dans une étape ultérieure de cette procédure pas à pas.
Tout en modifiant les propriétés de projet, cliquez sur l'onglet Signature. Sélectionnez l'option Signer l'assembly. Dans la liste Choisir un fichier de clé de nom fort, cliquez sur <Nouveau...>. Dans la zone Nom du fichier de clé, tapez key.snk. Désactivez la case à cocher Protéger mon fichier de clé par un mot de passe. Cliquez sur OK.
Ouvrez le fichier ISampleInterface.vb ou ISampleInterface.cs. Ajoutez le code suivant au fichier ISampleInterface pour créer l'interface ISampleInterface.
Imports System.Runtime.InteropServices <ComImport()> <Guid("8DA56996-A151-4136-B474-32784559F6DF")> Public Interface ISampleInterface Sub GetUserInput() ReadOnly Property UserInput As String ... End Interface
using System; using System.Runtime.InteropServices; namespace TypeEquivalenceInterface { [ComImport] [Guid("8DA56996-A151-4136-B474-32784559F6DF")] public interface ISampleInterface { void GetUserInput(); string UserInput { get; } ... } }
Dans le menu Outils, cliquez sur Create GUID. Dans la boîte de dialogue Create GUID, cliquez sur Format du Registre, puis sur Copier. Cliquez sur Quitter.
Dans l'attribut Guid, supprimez l'exemple de GUID et collez le GUID que vous avez copié à partir de la boîte de dialogue Create GUID. Supprimez les accolades ({}) du GUID copié.
Dans Visual Basic, dans le menu Projet, cliquez sur Afficher tous les fichiers. Ignorez cette étape si vous utilisez Visual C#.
Dans l'Explorateur de solutions, développez le dossier My Project si vous utilisez Visual Basic. Développez le dossier Propriétés si vous utilisez Visual C#. Double-cliquez sur le fichier AssemblyInfo.vb ou AssemblyInfo.cs. Ajoutez l'attribut suivant au fichier texte.
<Assembly: ImportedFromTypeLib("")>
[assembly: ImportedFromTypeLib("")]
Enregistrez le fichier.
Enregistrez le projet.
Cliquez avec le bouton droit sur le projet TypeEquivalenceInterface, puis cliquez sur 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éation d'une classe d'exécution
Pour créer le projet d'exécution d'équivalence des types
Dans Visual Studio, dans le menu Fichier, pointez sur Nouveau, puis cliquez sur Projet.
Dans la boîte de dialogue Nouveau projet, dans le volet Types de projets, vérifiez que Windows est sélectionné. Sélectionnez Bibliothèque de classes dans le volet Modèles. Dans la zone Nom, tapez TypeEquivalenceRuntime, puis cliquez sur OK. Le nouveau projet est créé.
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le fichier Class1.vb ou Class1.cs, puis cliquez sur Renommer. Renommez le fichier en SampleClass.vb ou SampleClass.cs et appuyez sur ENTRÉE. Lorsque vous renommez le fichier, la classe est également renommée en SampleClass. Cette classe implémentera l'interface ISampleInterface.
Cliquez avec le bouton droit sur le projet TypeEquivalenceRuntime, puis cliquez sur Propriétés. Cliquez sur l'onglet Compiler dans Visual Basic ou sur l'onglet Générer dans Visual C#. Affectez au chemin de sortie le même emplacement que celui que vous avez utilisé dans le projet TypeEquivalenceInterface, par exemple, C:\TypeEquivalenceSample.
Tout en modifiant les propriétés de projet, cliquez sur l'onglet Signature. Sélectionnez l'option Signer l'assembly. Dans la liste Choisir un fichier de clé de nom fort, cliquez sur <Nouveau...>. Dans la zone Nom du fichier de clé, tapez key.snk. Désactivez la case à cocher Protéger mon fichier de clé par un mot de passe. Cliquez sur OK.
Cliquez avec le bouton droit sur le projet TypeEquivalenceRuntime, puis cliquez sur Ajouter une référence. Cliquez sur l'onglet Parcourir et recherchez le dossier du chemin de sortie. Sélectionnez le fichier TypeEquivalenceInterface.dll et cliquez sur OK.
Dans Visual Basic, dans le menu Projet, cliquez sur Afficher tous les fichiers. Ignorez cette étape si vous utilisez Visual C#.
Dans l'Explorateur de solutions, développez le dossier Références. Sélectionnez la référence TypeEquivalenceInterface. Dans la fenêtre Propriétés de la référence TypeEquivalenceInterface, affectez à la propriété Version spécifique la valeur False.
Ajoutez le code suivant au fichier de classe SampleClass pour créer la classe SampleClass.
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
using System; using System.Collections.Generic; using System.Linq; using System.Text; 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(); } ... } }
Enregistrez le projet.
Cliquez avec le bouton droit sur le projet TypeEquivalenceRuntime, puis cliquez sur 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éation d'un projet client
Pour créer le projet client d'équivalence des types
Dans Visual Studio, dans le menu Fichier, pointez sur Nouveau, puis cliquez sur Projet.
Dans la boîte de dialogue Nouveau projet, dans le volet Types de projets, vérifiez que Windows est sélectionné. Sélectionnez Application console dans le volet Modèles. Dans la zone Nom, tapez TypeEquivalenceClient, puis cliquez sur OK. Le nouveau projet est créé.
Cliquez avec le bouton droit sur le projet TypeEquivalenceClient, puis cliquez sur Propriétés. Cliquez sur l'onglet Compiler dans Visual Basic ou sur l'onglet Générer dans Visual C#. Affectez au chemin de sortie le même emplacement que celui que vous avez utilisé dans le projet TypeEquivalenceInterface, par exemple, C:\TypeEquivalenceSample.
Cliquez avec le bouton droit sur le projet TypeEquivalenceClient, puis cliquez sur Ajouter une référence. Cliquez sur l'onglet Parcourir et recherchez le dossier du chemin de sortie. Sélectionnez le fichier TypeEquivalenceInterface.dll (pas le fichier TypeEquivalenceRuntime.dll) et cliquez sur OK.
Dans Visual Basic, dans le menu Projet, cliquez sur Afficher tous les fichiers. Ignorez cette étape si vous utilisez Visual C#.
Dans l'Explorateur de solutions, développez le dossier Références. Sélectionnez la référence TypeEquivalenceInterface. Dans la fenêtre Propriétés de la référence TypeEquivalenceInterface, affectez à la propriété Embed Interop Types (Incorporer les types d'interopérabilité) la valeur True.
Ajoutez le code suivant au fichier Module1.vb ou Program.cs pour créer le programme client.
Imports TypeEquivalenceInterface Imports System.Reflection 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
using System; using System.Collections.Generic; using System.Linq; using System.Text; using TypeEquivalenceInterface; using System.Reflection; 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(); } } }
Appuyez sur CTRL+F5 pour générer et exécuter le programme.
Modification de l'interface
Pour modifier l'interface
Dans Visual Studio, dans le menu Fichier, pointez sur Ouvrir, puis cliquez sur Projet/Solution.
Dans la boîte de dialogue Ouvrir un projet, cliquez avec le bouton droit sur le projet TypeEquivalenceInterface, puis cliquez sur Propriétés. Cliquez sur l'onglet Application. Cliquez sur le bouton Informations de l'assembly. Pour Version de l'assembly et Version de fichier, modifiez la valeur et choisissez 2.0.0.0.
Ouvrez le fichier ISampleInterface.vb ou ISampleInterface.cs. Ajoutez la ligne de code suivante à l'interface ISampleInterface :
Function GetDate() As Date
DateTime GetDate();
Enregistrez le fichier.
Enregistrez le projet.
Cliquez avec le bouton droit sur le projet TypeEquivalenceInterface, puis cliquez sur 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 la génération spécifié (par exemple, C:\TypeEquivalenceSample).
Modification de la classe d'exécution
Pour modifier la classe d'exécution
Dans Visual Studio, dans le menu Fichier, pointez sur Ouvrir, puis cliquez sur Projet/Solution.
Dans la boîte de dialogue Ouvrir un projet, cliquez avec le bouton droit sur le projet TypeEquivalenceRuntime et cliquez sur Propriétés. Cliquez sur l'onglet Application. Cliquez sur le bouton Informations de l'assembly. Pour Version de l'assembly et Version de fichier, modifiez la valeur et choisissez 2.0.0.0.
Ouvrez le fichier SampleClass.vb ou SampleClass.cs. Ajoutez les lignes suivantes à la classe SampleClass.
Public Function GetDate() As DateTime Implements ISampleInterface.GetDate Return Now End Function
public DateTime GetDate() { return DateTime.Now; }
Enregistrez le fichier.
Enregistrez le projet.
Cliquez avec le bouton droit sur le projet TypeEquivalenceRuntime, puis cliquez sur Générer. Une version mise à jour du fichier .dll de bibliothèque de classes est compilée et enregistrée dans le chemin de sortie de la génération précédemment spécifié (par exemple, C:\TypeEquivalenceSample).
Dans l'Explorateur de fichiers, ouvrez le dossier du chemin de sortie (par exemple, C:\TypeEquivalenceSample). Double-cliquez sur le fichier TypeEquivalenceClient.exe pour exécuter le programme. Le programme reflétera la nouvelle version de l'assembly TypeEquivalenceRuntime sans aucune recompilation.
Voir aussi
Référence
/link (Options du compilateur C#)