Procédure pas à pas : activation de la compatibilité descendante lorsque votre hôte change
Cette procédure pas à pas décrit la version 2 du pipeline présenté dans Procédure pas à pas : création d'une application extensible. La version 2 inclut davantage de fonctionnalités de calcul en fournissant une chaîne d'opérations arithmétiques délimitée par des virgules qu'elle prend en charge pour l'hôte. L'hôte peut ensuite choisir une opération et soumettre au complément une équation à calculer.
Le pipeline dispose d'un nouvel hôte et d'un nouveau contrat. Pour permettre à la version 1 du complément de fonctionner avec un nouvel hôte et un nouveau contrat, le pipeline inclut la vue de complément utilisée pour la version 1 et un adaptateur côté complément qui convertit les données de l'ancienne vue de complément en nouveau contrat. L'illustration suivante indique comment ces deux compléments peuvent fonctionner avec le même hôte.
Nouvel hôte, anciens compléments
Ce pipeline est également décrit dans Scénarios de pipelines de compléments.
Cette procédure pas à pas décrit les tâches suivantes :
Création d'une solution Visual Studio.
Création de la structure de répertoires du pipeline.
Création du contrat et des vues.
Création de l'adaptateur côté complément, qui inclut des adaptateurs pour la nouvelle version du complément et pour la version 1 du complément.
Création de l'adaptateur côté hôte.
Création de l'hôte.
Création du complément.
Déploiement du pipeline.
Exécution de l'application hôte.
La procédure pas à pas montre également utiliser des classes de base abstraites pour définir des vues, et démontre que ces vues sont compatibles avec les vues définies par les interfaces. L'utilisation d'interfaces est recommandée.
Remarque |
---|
Une partie du code indiqué dans cette procédure pas à pas contient des références à des espaces de noms superflues.Les étapes de la procédure reflètent correctement les références requises en Visual Studio. |
Vous trouverez des exemples de code supplémentaires, ainsi que des présentations technologiques destinées aux clients des outils de génération de pipelines de compléments, sur le site Managed Extensibility and Add-In Framework (en anglais) de CodePlex.
Composants requis
Pour exécuter cette procédure pas à pas, vous devez disposer des composants suivants :
Visual Studio.
La version 1 du pipeline décrite dans Procédure pas à pas : création d'une application extensible. Étant donné que la version 2 utilise des segments de pipeline développés dans la version 1, vous devez développer et déployer la version 1 du pipeline avant d'exécuter les étapes de cette rubrique.
Création d'une solution Visual Studio
Utilisez une solution dans Visual Studio pour contenir les projets de vos segments de pipeline.
Pour créer la solution de pipeline
Dans Visual Studio, créez un nouveau projet nommé Calc2Contract. Basez-le sur le modèle Bibliothèque de classes.
Nommez la solution CalculatorV2.
Création de la structure de répertoires du pipeline
Le modèle de complément requiert que les assemblys du segment de pipeline soient placés dans une structure de répertoires spécifiée.
Pour créer la structure de répertoires du pipeline
Si vous ne l'avez pas déjà fait, ajoutez le dossier CalcV2 à la structure des dossiers de pipeline que vous avez créée dans Procédure pas à pas : création d'une application extensible. Le dossier CalcV2 contiendra la nouvelle version du complément.
Pipeline AddIns CalcV1 CalcV2 AddInSideAdapters AddInViews Contracts HostSideAdapters
Il n'est pas nécessaire de placer la structure des dossiers de pipeline dans votre dossier d'application ; ceci est effectué uniquement pour des raisons de commodité dans ces procédures pas à pas. Si vous avez placé votre structure des dossiers de pipeline dans un emplacement différent dans la première procédure pas à pas, suivez le même modèle pour cette procédure pas à pas. Consultez la description des spécifications de répertoires du pipeline dans Spécifications du développement de pipelines.
Création du contrat et des vues
Le segment de contrat pour ce pipeline définit l'interface ICalc2Contract, qui dispose des deux méthodes suivantes :
Méthode GetAvailableOperations.
Cette méthode retourne la chaîne des opérations mathématiques que le complément prend en charge pour l'hôte. La version 2 prend en charge cinq opérations et cette méthode retourne la chaîne "+,-,*,/,**" où "**" représente l'opération Pow.
Dans les vues hôte et de complément, cette méthode est nommée Operations au lieu de GetAvailableOperations.
Vous pouvez exposer des méthodes sur le contrat comme propriétés sur les vues en convertissant l'appel de méthode en une propriété sur l'adaptateur.
Méthode Operate.
L'hôte appelle cette méthode pour soumettre au complément une équation qu'il doit calculer et dont il doit retourner le résultat.
Pour créer le contrat
Dans la solution Visual Studio nommée CalculatorV2, ouvrez le projet Calc2Contract.
Dans l'Explorateur de solutions, ajoutez au projet Calc2Contract des références aux assemblys suivants :
System.AddIn.Contract.dll
System.AddIn.dll
Dans l'Explorateur de solutions, excluez la classe par défaut ajoutée aux nouveaux projets Bibliothèque de classes.
Ajoutez un nouvel élément au projet, à l'aide du modèle Interface. Dans la boîte de dialogue Ajouter un nouvel élément, nommez l'interface ICalc2Contract.
Dans le fichier d'interface, ajoutez des références d'espace de noms à System.AddIn.Contract et System.AddIn.Pipeline.
Utilisez le code suivant pour compléter le segment de contrat. Notez que cette interface doit avoir l'attribut AddInContractAttribute.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Contract Imports System.AddIn.Pipeline Namespace CalculatorContracts <AddInContract()> _ Public Interface ICalc2Contract Inherits IContract Function GetAvailableOperations() As String Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double End Interface End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn.Contract; using System.AddIn.Pipeline; namespace CalculatorContracts { [AddInContract] public interface ICalc2Contract : IContract { string GetAvailableOperations(); double Operate(String operation, double a, double b); } }
Étant donné que la vue de complément et la vue hôte ont le même code, vous pouvez facilement créer ces vues en même temps. Elles diffèrent par un seul facteur : la vue de complément requiert l'attribut AddInBaseAttribute ; la vue hôte du complément ne requiert aucun attribut.
Pour créer la vue de complément pour la version 2
Ajoutez un nouveau projet nommé Calc2AddInView à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.
Dans l'Explorateur de solutions, ajoutez au projet Calc2AddInView une référence à System.AddIn.dll.
Renommez la classe Calculator2.
Dans le fichier de classe, ajoutez une référence d'espace de noms à System.AddIn.Pipeline.
Définissez Calculator2 comme une classe abstract (classe MustInherit en Visual Basic).
Utilisez le code suivant pour cette vue de complément. Notez que cette classe doit avoir l'attribut AddInBaseAttribute.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Pipeline Namespace CalcAddInViews <AddInBase()> _ Public MustInherit Class Calculator2 Public MustOverride ReadOnly Property Operations() As String Public MustOverride Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double End Class End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn.Pipeline; namespace CalcAddInViews { [AddInBase] public abstract class Calculator2 { public abstract string Operations { get; } public abstract double Operate(string operation, double a, double b); } }
Pour créer la vue hôte du complément
Ajoutez un nouveau projet nommé Calc2HVA à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.
Renommez la classe Calculator.
Définissez Calculator comme une classe abstract (classe MustInherit en Visual Basic).
Dans le fichier de classe, utilisez le code suivant pour créer la vue hôte du complément.
Imports Microsoft.VisualBasic Imports System Namespace CalcHVAs Public MustInherit Class Calculator Public MustOverride ReadOnly Property Operations() As String Public MustOverride Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double End Class End Namespace
namespace CalcHVAs { public abstract class Calculator { public abstract string Operations { get; } public abstract double Operate(string operation, double a, double b); } }
Pour montrer l'utilisation de la version 1 du complément avec le nouvel hôte, la solution doit inclure la vue du complément créée pour la version 1 du complément de calculatrice.
Pour ajouter le projet de vue de complément de la version 1
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur la solution CalculatorV2.
Cliquez sur Ajouter, puis sur Projet existant.
Accédez aux dossiers qui contiennent la solution CalculatorV1 et sélectionnez le fichier projet pour le projet Calc1AddInView.
Création de l'adaptateur côté complément
Cet adaptateur côté complément est constitué de deux adaptateurs de vue en contrat : l'un pour adapter la vue de la version 2 du complément à la version 2 du contrat et l'autre pour adapter la vue de la version 1 du complément à la version 2 du contrat.
Dans ce pipeline, le complément fournit un service à l'hôte et les types circulent du complément vers l'hôte. Étant donné qu'aucun type ne circule de l'hôte vers le complément, vous n'avez pas à inclure un adaptateur de contrat en vue.
Pour créer l'adaptateur côté complément
Ajoutez un nouveau projet nommé Calc2AddInSideAdapter à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.
Dans l'Explorateur de solutions, ajoutez au projet Calc2AddInSideAdapter des références aux assemblys suivants :
System.AddIn.dll
System.AddIn.Contract.dll
Ajoutez des références de projet aux projets suivants :
Calc2AddInView
Calc2Contract
Sélectionnez chaque référence de projet puis, dans Propriétés, affectez la valeur False à Copie locale, afin d'empêcher que les assemblys référencés soient copiés dans le dossier de génération local. Les assemblys se trouvent dans le répertoire de pipeline, comme décrit un peu loin dans la section « Déployer le pipeline » de cette procédure. En Visual Basic, utilisez l'onglet Références de Propriétés du projet pour affecter à Copie locale la valeur False pour les deux références de projet.
Renommez la classe par défaut du projet CalculatorViewToContractAddInSideAdapter.
Dans le fichier de classe, ajoutez une référence d'espace de noms à System.AddIn.Pipeline.
Dans le fichier de classe, ajoutez des références d'espace de noms aux segments adjacents : CalcAddInViews et CalculatorContracts. (En Visual Basic, ces références d'espace de noms sont Calc2AddInView.CalcAddInViews et Calc2Contract.CalculatorContracts, à moins que vous ayez désactivé les espaces de noms par défaut dans vos projets Visual Basic.)
Utilisez le code suivant pour cet adaptateur côté complément. Le modèle d'implémentation est semblable à l'adaptateur côté complément pour la version 1, bien que l'interface de contrat soit très différente.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Pipeline Imports System.AddIn.Contract Imports Calc2Contract.CalculatorContracts Imports Calc2AddInView.CalcAddInViews Namespace CalculatorContractsAddInAdapters <AddInAdapterAttribute()> _ Public Class CalculatorViewToContractAddInAdapter Inherits ContractBase Implements ICalc2Contract Private _view As Calculator2 Public Sub New(ByVal calculator As Calculator2) _view = calculator End Sub Public Function GetAvailableOperations() As String Implements ICalc2Contract.GetAvailableOperations Return _view.Operations End Function Public Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double Implements ICalc2Contract.Operate Return _view.Operate(operation, a, b) End Function End Class End Namespace
using System.AddIn.Pipeline; using CalcAddInViews; using CalculatorContracts; namespace CalcAddInSideAdapters { [AddInAdapterAttribute] public class CalculatorViewToContractAddInAdapter : ContractBase, ICalc2Contract { private Calculator2 _view; public CalculatorViewToContractAddInAdapter(Calculator2 calculator) { _view = calculator; } public string GetAvailableOperations() { return _view.Operations; } public double Operate(string operation, double a, double b) { return _view.Operate(operation, a, b); } } }
Pour permettre à la version 1 du complément de communiquer avec le nouvel hôte, le pipeline pour la version 1 requiert un adaptateur côté complément qui convertit les données de l'ancienne vue de complément en nouveau contrat.
Pour créer l'adaptateur côté complément de la version 1 à la version 2
Ajoutez un nouveau projet nommé Calc2V1toV2AddInSideAdapter à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.
Dans l'Explorateur de solutions, ajoutez au projet Calc2V1toV2AddInSideAdapter des références aux assemblys suivants :
System.AddIn.dll
System.AddIn.Contract.dll
Ajoutez des références de projet aux projets suivants :
Calc1AddInView
Calc2Contract
Sélectionnez chaque référence de projet puis, dans Propriétés, affectez la valeur False à Copie locale, afin d'empêcher que les assemblys référencés soient copiés dans le dossier de génération local. En Visual Basic, utilisez l'onglet Références de Propriétés du projet pour affecter à Copie locale la valeur False pour les deux références de projet.
Renommez la classe par défaut du projet Calc2V1ViewToV2ContractAddInSideAdapter.
Dans le fichier de classe, ajoutez une référence d'espace de noms à System.AddIn.Pipeline.
Dans le fichier de classe, ajoutez des références d'espace de noms aux segments adjacents : CalcAddInViews et CalculatorContracts. (En Visual Basic, ces références d'espace de noms sont Calc1AddInView.CalcAddInViews et Calc2Contract.CalculatorContracts, à moins que vous ayez désactivé les espaces de noms par défaut dans vos projets Visual Basic.) Notez que l'espace de noms de vue provient de la version 1 et le contrat de la version 2.
Appliquez l'attribut AddInAdapterAttribute à la classe Calc2V1ViewToV2ContractAddInSideAdapter, pour l'identifier comme adaptateur côté complément.
Définissez la classe Calc2V1ViewToV2ContractAddInSideAdapter pour qu'elle hérite de ContractBase, ce qui fournit une implémentation par défaut de l'interface IContract et implémente la version 2 de l'interface de contrat pour le pipeline, ICalc2Contract.
Ajoutez un constructeur public qui accepte un ICalculator, le met en cache dans un champ privé et appelle le constructeur de classe de base.
Pour implémenter les membres de ICalc2Contract, vous devez appeler les membres appropriés de l'instance ICalculator qui est passée au constructeur, et retourner les résultats. À cause des différences entre la version 1 et la version 2 des interfaces de contrat, vous devez avoir une instruction switch (instructionSelect Case en Visual Basic) pour adapter la vue (ICalculator) au contrat (ICalc2Contract).
Le code suivant affiche l'adaptateur côté complément terminé.
Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Pipeline Imports Calc1AddInView.CalcAddInViews Imports Calc2Contract.CalculatorContracts Namespace AddInSideV1toV2Adapter <AddInAdapter()> _ Public Class Calc2V1ViewToV2ContractAddInSideAdapter Inherits ContractBase Implements ICalc2Contract Private _view As ICalculator Public Sub New(ByVal calc As ICalculator) MyBase.New() _view = calc End Sub Public Function GetAvailableOperations() As String Implements ICalc2Contract.GetAvailableOperations Return "+, -, *, /" End Function Public Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) _ As Double Implements ICalc2Contract.Operate Select Case (operation) Case "+" Return _view.Add(a, b) Case "-" Return _view.Subtract(a, b) Case "*" Return _view.Multiply(a, b) Case "/" Return _view.Divide(a, b) Case Else Throw New InvalidOperationException(("This add-in does not support: " + operation)) End Select End Function End Class End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn.Pipeline; using CalcAddInViews; using CalculatorContracts; namespace AddInSideV1toV2Adapter { [AddInAdapter] public class Calc2V1ViewToV2ContractAddInSideAdapter : ContractBase, ICalc2Contract { ICalculator _view; public Calc2V1ViewToV2ContractAddInSideAdapter(ICalculator calc) { _view = calc; } public string GetAvailableOperations() { return "+, -, *, /" ; } public double Operate(string operation, double a, double b) { switch (operation) { case "+": return _view.Add(a, b); case "-": return _view.Subtract(a, b); case "*": return _view.Multiply(a, b); case "/": return _view.Divide(a, b); default: throw new InvalidOperationException("This add-in does not support: " + operation); } } } }
Création de l'adaptateur côté hôte
Cet adaptateur côté hôte se compose d'un adaptateur de contrat en vue. Un adaptateur de contrat en vue est suffisant pour prendre en charge le deux versions du complément, car chaque adaptateur côté complément effectue la conversion de sa propre vue en contrat de version 2.
Dans ce pipeline, le complément fournit un service à l'hôte et les types circulent du complément vers l'hôte. Étant donné qu'aucun type ne circule de l'hôte vers le complément, vous n'avez pas à inclure un adaptateur de vue en contrat.
Pour implémenter la gestion de la durée de vie, utilisez un objet ContractHandle pour attacher un jeton de durée de vie au contrat. Vous devez conserver une référence à ce handle afin que la gestion de la durée de vie fonctionne. Une fois que le jeton est appliqué, aucune programmation supplémentaire n'est nécessaire, car le système de complément peut supprimer les objets lorsqu'ils ne sont plus utilisés et les rendre disponibles pour le garbage collection. Pour plus d'informations, consultez Gestion de la durée de vie.
Pour créer l'adaptateur côté hôte
Ajoutez un nouveau projet nommé Calc2HostSideAdapter à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.
Dans l'Explorateur de solutions, ajoutez au projet Calc2HostSideAdapter des références aux assemblys suivants :
System.AddIn.dll
System.AddIn.Contract.dll
Ajoutez des références de projet aux projets suivants :
Calc2Contract
Calc2HVA
Sélectionnez chaque référence de projet puis, dans Propriétés, affectez la valeur False à Copie locale, afin d'empêcher que les assemblys référencés soient copiés dans le dossier de génération local. En Visual Basic, utilisez l'onglet Références de Propriétés du projet pour affecter à Copie locale la valeur False pour les deux références de projet.
Renommez la classe par défaut du projet CalculatorContractToViewHostSideAdapter.
Dans le fichier de classe, ajoutez des références d'espace de noms à System.AddIn.Pipeline.
Dans le fichier de classe, ajoutez des références d'espace de noms aux segments adjacents : CalcHVAs et CalculatorContracts. (En Visual Basic, ces références d'espace de noms sont Calc2HVA.CalcHVAs et Calc2Contract.CalculatorContracts, à moins que vous ayez désactivé les espaces de noms par défaut dans vos projets Visual Basic.)
Appliquez l'attribut HostAdapterAttribute à la classe CalculatorContractToViewHostSideAdapter, pour l'identifier comme adaptateur côté hôte.
Définissez la classe CalculatorContractToViewHostSideAdapter pour qu'elle hérite de la classe abstraite de base qui représente la vue hôte du complément : CalcHVAs.Calculator (Calc2HVA.CalcHVAs.Calculator en Visual Basic). Notez la différence par rapport à la version 1, où la vue hôte du complément est une interface.
Ajoutez un constructeur public qui accepte le type du contrat du pipeline, ICalc2Contract. Le constructeur doit mettre en cache la référence au contrat. Il doit également créer et mettre en cache un nouveau ContractHandle pour le contrat, pour gérer la durée de vie du complément.
Important ContractHandle est critique pour la gestion de la durée de vie.Si vous ne parvenez pas à conserver une référence à l'objet ContractHandle, le garbage collection la récupérera, et le pipeline s'arrêtera quand le programme ne s'y attend pas.Cela peut provoquer des erreurs difficiles à diagnostiquer, telles que AppDomainUnloadedException.L'arrêt est une étape normale dans la vie d'un pipeline ; il est donc impossible pour le code de gestion de la durée de vie de détecter que cette condition est une erreur.
Lorsque vous substituez les membres de Calculator, appelez simplement les membres correspondants de l'instance ICalc2Contract passée au constructeur et retournez les résultats. Cela adapte le contrat (ICalc2Contract) à la vue (Calculator).
Le code suivant affiche le segment d'adaptateur côté hôte terminé.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Pipeline Imports Calc2HVA.CalcHVAs Imports Calc2Contract.CalculatorContracts Namespace CalculatorContractsHostAdapers <HostAdapter()> _ Public Class CalculatorContractToViewHostAdapter Inherits Calculator Private _contract As ICalc2Contract Private _handle As ContractHandle Public Sub New(ByVal contract As ICalc2Contract) _contract = contract _handle = New ContractHandle(contract) End Sub Public Overrides ReadOnly Property Operations() As String Get Return _contract.GetAvailableOperations() End Get End Property Public Overrides Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double Return _contract.Operate(operation, a, b) End Function End Class End Namespace
using System.AddIn.Pipeline; using CalcHVAs; using CalculatorContracts; namespace CalcHostSideAdapters { [HostAdapter] public class CalculatorContractToViewHostAdapter : Calculator { private CalculatorContracts.ICalc2Contract _contract; private System.AddIn.Pipeline.ContractHandle _handle; public CalculatorContractToViewHostAdapter(ICalc2Contract contract) { _contract = contract; _handle = new System.AddIn.Pipeline.ContractHandle(contract); } public override string Operations { get { return _contract.GetAvailableOperations(); } } public override double Operate(string operation, double a, double b) { return _contract.Operate(operation, a, b); } } }
Création de l'hôte
Une application hôte interagit avec le complément via la vue hôte. Elle utilise les méthodes d'activation et de découverte de complément fournies par les classes AddInStore et AddInToken pour effectuer les opérations suivantes :
Régénérer le cache du pipeline et les informations de complément.
Rechercher des compléments de type Calculator sous le répertoire racine du pipeline spécifié.
Inviter l'utilisateur à spécifier le complément à utiliser. Dans cet exemple, vous visualiserez deux compléments disponibles.
Activer le complément sélectionné dans un nouveau domaine d'application avec un niveau de confiance de sécurité spécifié.
Exécuter la méthode RunCalculator, qui appelle les méthodes du complément telles qu'elles sont fournies par la vue hôte du complément.
Pour créer l'hôte
Ajoutez un nouveau projet nommé MathHost2 à la solution CalculatorV2. Basez-le sur le modèle Application console.
Dans l'Explorateur de solutions, ajoutez au projet MathHost2 une référence à l'assembly System.AddIn.dll.
Ajoutez une référence de projet au projet Calc2HVA. Sélectionnez la référence de projet puis, dans Propriétés, affectez la valeur False à Copie locale, afin d'empêcher que l'assembly référencé soit copié dans le dossier de génération local. En Visual Basic, utilisez l'onglet Références de Propriétés du projet pour affecter à Copie locale la valeur False.
Renommez le fichier de classe (module en Visual Basic) MathHost2.
En Visual Basic, utilisez l'onglet Application de la boîte de dialogue Propriétés du projet pour affecter à Objet de démarrage la valeur Sub Main.
Dans le fichier de classe ou de module, ajoutez une référence d'espace de noms à System.AddIn.Hosting.
Dans le fichier de classe ou de module, ajoutez une référence d'espace de noms pour la vue hôte du complément : CalcHVAs. (En Visual Basic, cette référence d'espace de noms est Calc2HVA.CalcHVAs, à moins que vous ayez désactivé les espaces de noms par défaut dans vos projets Visual Basic.)
Dans l'Explorateur de solutions, sélectionnez la solution puis, dans le menu Projet, sélectionnez Propriétés. Dans la boîte de dialogue Pages de propriétés de Solution, définissez le Projet de démarrage unique comme projet d'application hôte.
Utilisez le code suivant pour créer l'application hôte.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Collections.ObjectModel Imports System.Text Imports System.AddIn.Hosting Imports Calc2HVA.CalcHVAs Namespace Mathhost Module MathHost2 Sub Main() ' Assume that the current directory is the application folder, ' and that it contains the pipeline folder structure. Dim pipeRoot As String = Environment.CurrentDirectory & "\Pipeline" ' Rebuild the cache of pipline and add-in information. AddInStore.Rebuild(pipeRoot) ' Find add-ins of type Calculator under the specified pipeline root directory. Dim tokens As Collection(Of AddInToken) = AddInStore.FindAddIns(GetType(Calculator), pipeRoot) ' Determine which add-in to use. Dim calcToken As AddInToken = ChooseCalculator(tokens) ' Activate the selected AddInToken in a new ' application domain with a specified security trust level. Dim calculator As Calculator = calcToken.Activate(Of Calculator)(AddInSecurityLevel.Internet) ' Run the calculator. RunCalculator(calculator) End Sub Private Function ChooseCalculator(ByVal tokens As Collection(Of AddInToken)) As AddInToken If tokens.Count = 0 Then Console.WriteLine("No calculators are available") Return Nothing End If Console.WriteLine("Available Calculators: ") ' Show the token properties for each token ' in the AddInToken collection (tokens), ' preceded by the add-in number in [] brackets. Dim tokNumber As Integer = 1 For Each tok As AddInToken In tokens Console.WriteLine(vbTab & "[{0}]: {1} - {2}" & _ vbLf & vbTab & "{3}" & _ vbLf & vbTab & "{4}" & _ vbLf & vbTab & "{5} - {6}", _ tokNumber.ToString, tok.Name, _ tok.AddInFullName, tok.AssemblyName, _ tok.Description, tok.Version, tok.Publisher) tokNumber = tokNumber + 1 Next Console.WriteLine("Which calculator do you want to use?") Dim line As String = Console.ReadLine() Dim selection As Integer If Int32.TryParse(line, selection) Then If selection <= tokens.Count Then Return tokens(selection - 1) End If End If Console.WriteLine("Invalid selection: {0}. Please choose again.", line) Return ChooseCalculator(tokens) End Function Private Sub RunCalculator(ByVal calc As Calculator) If calc Is Nothing Then 'No calculators were found, read a line and exit Console.ReadLine() End If Console.WriteLine("Available operations: " & calc.Operations) Console.WriteLine("Request a calculation , such as: 2 + 2") Console.WriteLine("Type ""exit"" to exit") Dim line As String = Console.ReadLine() Do While Not line.Equals("exit") ' Parser Try Dim c As Parser = New Parser(line) Console.WriteLine(calc.Operate(c.action, c.A, c.B)) Catch Console.WriteLine("Invalid command: {0}. Commands must be formated: [number] [operation] [number]", line) Console.WriteLine("Available operations: " & calc.Operations) End Try line = Console.ReadLine() Loop End Sub End Module Friend Class Parser Public partA As Double Public partB As Double Public action As String Friend Sub New(ByVal line As String) MyBase.New() Dim parts() As String = line.Split(" ") partA = Double.Parse(parts(0)) action = parts(1) partB = Double.Parse(parts(2)) End Sub Public ReadOnly Property A() As Double Get Return partA End Get End Property Public ReadOnly Property B() As Double Get Return partB End Get End Property Public ReadOnly Property CalcAction() As String Get Return action End Get End Property End Class End Namespace
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using System.AddIn.Hosting; using CalcHVAs; namespace MathHost { class Program { static void Main() { // Assume that the current directory is the application folder, // and that it contains the pipeline folder structure. String addInRoot = Environment.CurrentDirectory + "\\Pipeline"; //Check to see if new add-ins have been installed. AddInStore.Rebuild(addInRoot); //Search for Calculator add-ins. Collection<AddInToken> tokens = AddInStore.FindAddIns(typeof(Calculator), addInRoot); //Ask the user which add-in they would like to use. AddInToken calcToken = ChooseCalculator(tokens); //Activate the selected AddInToken in a new //application domain with the Internet trust level. Calculator calculator = calcToken.Activate<Calculator>(AddInSecurityLevel.Internet); //Run the add-in. RunCalculator(calculator); } private static AddInToken ChooseCalculator(Collection<AddInToken> tokens) { if (tokens.Count == 0) { Console.WriteLine("No calculators are available"); return null; } Console.WriteLine("Available Calculators: "); // Show the token properties for each token // in the AddInToken collection (tokens), // preceded by the add-in number in [] brackets. int tokNumber = 1; foreach (AddInToken tok in tokens) { Console.WriteLine(String.Format("\t[{0}]: {1} - {2}\n\t{3}\n\t\t {4}\n\t\t {5} - {6}", tokNumber.ToString(), tok.Name, tok.AddInFullName, tok.AssemblyName, tok.Description, tok.Version, tok.Publisher)); tokNumber++; } Console.WriteLine("Which calculator do you want to use?"); String line = Console.ReadLine(); int selection; if (Int32.TryParse(line, out selection)) { if (selection <= tokens.Count) { return tokens[selection - 1]; } } Console.WriteLine("Invalid selection: {0}. Please choose again.", line); return ChooseCalculator(tokens); } private static void RunCalculator(Calculator calc) { if (calc == null) { //No calculators were found, read a line and exit. Console.ReadLine(); } Console.WriteLine("Available operations: " + calc.Operations); Console.WriteLine("Type \"exit\" to exit"); String line = Console.ReadLine(); while (!line.Equals("exit")) { // The Parser class parses the user's input. try { Parser c = new Parser(line); Console.WriteLine(calc.Operate(c.Action, c.A, c.B)); } catch { Console.WriteLine("Invalid command: {0}. Commands must be formated: [number] [operation] [number]", line); Console.WriteLine("Available operations: " + calc.Operations); } line = Console.ReadLine(); } } } internal class Parser { internal Parser(String line) { String[] parts = line.Trim().Split(' '); a = Double.Parse(parts[0]); action = parts[1]; b = Double.Parse(parts[2]); } double a; public double A { get { return a; } } double b; public double B { get { return b; } } String action; public String Action { get { return action; } } } }
Remarque Ce code suppose que la structure des dossiers de pipeline est localisée dans le dossier d'application.Si vous l'avez localisé ailleurs, modifiez la ligne de code qui définit la variable addInRoot, afin que cette variable contienne le chemin d'accès à votre structure de répertoires du pipeline.
Création du complément
Un complément implémente les méthodes spécifiées par la vue de complément. Dans ce complément, la méthode Operations retourne une chaîne qui répertorie les opérations mathématiques que le complément prend en charge. La méthode Operate fournit le code pour calculer le résultat d'après la sélection, par l'hôte, d'une opération et de deux nombres.
Pour créer le complément
Ajoutez un nouveau projet nommé AddInCalcV2 à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.
Dans l'Explorateur de solutions, ajoutez des références aux assemblys suivants au projet AddInCalcV2 :
System.AddIn.dll
System.AddIn.Contract.dll
Ajoutez une référence de projet au projet Calc2AddInView. Sélectionnez la référence de projet puis, dans Propriétés, affectez la valeur False à Copie locale, afin d'empêcher que l'assembly référencé soit copié dans le dossier de génération local. En Visual Basic, utilisez l'onglet Références de Propriétés du projet pour affecter à Copie locale la valeur False.
Renommez le fichier de classe SampleV2AddIn.
Dans le fichier de classe, ajoutez des références d'espace de noms à System.AddIn et System.AddIn.Pipeline. System.AddIn.Pipeline est requis uniquement parce que le code inclut un exemple de l'attribut QualificationDataAttribute.
Dans le fichier de classe, ajoutez une référence d'espace de noms pour la version 2 du segment de vue de complément : CalcAddInViews (Calc2AddInView.CalcAddInViews en Visual Basic).
Appliquez l'attribut AddInAttribute à la classe SampleV2AddIn, pour identifier la classe comme un complément.
Appliquez l'attribut QualificationDataAttribute à la classe SampleV2AddIn et spécifiez des informations que l'hôte peut extraire du AddInToken. Dans ce cas, les informations suggèrent que le complément doit être chargé dans son propre domaine d'application. Consultez Comment : utiliser des données de qualification.
Définissez la classe SampleV2AddIn pour qu'elle hérite de la classe abstraite de base qui représente la vue du complément : Calculator2.
Substituez les membres de Calculator2 et retournez les résultats des calculs appropriés.
Le code suivant montre le complément terminé.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn Imports System.AddIn.Pipeline Imports Calc2AddInView.CalcAddInViews Namespace CalculatorAddIns ' This pipeline segment has ' two attributes: ' 1 - An AddInAttribute to identify ' this segment as an add-in. ' ' 2 - A QualificationDataAttribute to ' indicate that the add-in should ' be loaded into a new application domain. <AddIn("Calculator Add-in", Version:="2.0.0.0")> _ <QualificationData("Isolation", "NewAppDomain")> _ Public Class SampleV2AddIn Inherits Calculator2 Public Overrides ReadOnly Property Operations() As String Get Return "+, -, *, /, **" End Get End Property Public Overrides Function Operate(ByVal operation As String, _ ByVal a As Double, ByVal b As Double) As Double Select Case operation Case "+" Return a + b Case "-" Return a - b Case "*" Return a * b Case "/" Return a / b Case "**" Return Math.Pow(a, b) Case Else Throw New InvalidOperationException("This add-in does not support: " & operation) End Select End Function End Class End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn; using System.AddIn.Pipeline; using CalcAddInViews; namespace CalcAddIns { // This pipeline segment has // two attributes: // 1 - An AddInAttribute to identify // this segment as an add-in. // // 2 - A QualificationDataAttribute to // indicate that the add-in should // be loaded into a new application domain. [AddIn("Calculator Add-in",Version="2.0.0.0")] [QualificationData("Isolation", "NewAppDomain")] public class SampleV2AddIn : Calculator2 { public override string Operations { get { return "+, -, *, /, **"; } } public override double Operate(string operation, double a, double b) { switch (operation) { case "+": return a + b; case "-": return a - b; case "*": return a * b; case "/": return a / b; case "**": return Math.Pow(a, b); default: throw new InvalidOperationException("This add-in does not support: " + operation); } } } }
Déploiement du pipeline
Vous êtes maintenant prêt à générer et déployer les segments de complément vers la structure de répertoires du pipeline requise.
Pour déployer les segments vers le pipeline
Pour chaque projet dans la solution, utilisez l'onglet Génération de Propriétés du projet (onglet Compiler en Visual Basic) pour définir la valeur du Chemin de sortie (Chemin de sortie de la génération en Visual Basic). Si vous avez nommé votre dossier d'application MyApp, par exemple, vos projets seraient générés dans les dossiers suivants :
Projet
Chemin d'accès
AddInCalcV2
MyApp\Pipeline\AddIns\CalcV2
Calc2AddInSideAdapter
MyApp\Pipeline\AddInSideAdapters
Calc2V1toV2AddInSideAdapter
MyApp\Pipeline\AddInSideAdapters
Calc1AddInView
MyApp\Pipeline\AddInViews
Calc2AddInView
MyApp\Pipeline\AddInViews
Calc2Contract
MyApp\Pipeline\Contracts
MathHost2
MyApp
Calc2HostSideAdapter
MyApp\Pipeline\HostSideAdapters
Calc2HVA
MyApp
Remarque Si vous placez votre structure des dossiers de pipeline dans un emplacement autre que votre dossier d'application, vous devez modifier les chemins d'accès affichés dans ce tableau en conséquence.
Générez la solution Visual Studio.
Vérifiez les répertoires de l'application et du pipeline pour vous assurer que les assemblys ont été copiés dans les répertoires corrects et qu'aucune copie supplémentaire des assemblys n'a été installée dans des dossiers incorrects.
Remarque Si vous n'avez pas changé Copie locale en False pour la référence de projet Calc2AddInView dans le projet AddInCalcV2, les problèmes du contexte du chargeur empêcheront la localisation du complément.
Pour plus d'informations sur le déploiement vers le pipeline, consultez Spécifications du développement de pipelines.
Exécution de l'application hôte
Vous êtes maintenant prêt à exécuter l'hôte et à interagir avec les compléments.
Pour exécuter l'application hôte
Assurez-vous que les deux versions du complément sont déployées.
À l'invite de commandes, accédez au répertoire de l'application et exécutez l'application hôte. Dans cet exemple, l'application hôte est MathHost2.exe.
L'hôte recherche tous les compléments disponibles de son type et vous invite à sélectionner un complément. Entrez 1 ou 2.
Entrez une équation pour la calculatrice, telle que 2 + 2.
Tapez quitter, puis appuyez sur la touche Entrée pour fermer l'application.
Répétez les étapes 2 à 5 pour exécuter l'autre complément.
Voir aussi
Tâches
Procédure pas à pas : création d'une application extensible
Procédure pas à pas : passage de collections entre des hôtes et des compléments