Partager via


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

Scénario de pipeline : 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.

RemarqueRemarque

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

  1. Dans Visual Studio, créez un nouveau projet nommé Calc2Contract. Basez-le sur le modèle Bibliothèque de classes.

  2. 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

  1. Dans la solution Visual Studio nommée CalculatorV2, ouvrez le projet Calc2Contract.

  2. Dans l'Explorateur de solutions, ajoutez au projet Calc2Contract des références aux assemblys suivants :

    System.AddIn.Contract.dll

    System.AddIn.dll

  3. Dans l'Explorateur de solutions, excluez la classe par défaut ajoutée aux nouveaux projets Bibliothèque de classes.

  4. 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.

  5. Dans le fichier d'interface, ajoutez des références d'espace de noms à System.AddIn.Contract et System.AddIn.Pipeline.

  6. 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

  1. Ajoutez un nouveau projet nommé Calc2AddInView à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.

  2. Dans l'Explorateur de solutions, ajoutez au projet Calc2AddInView une référence à System.AddIn.dll.

  3. Renommez la classe Calculator2.

  4. Dans le fichier de classe, ajoutez une référence d'espace de noms à System.AddIn.Pipeline.

  5. Définissez Calculator2 comme une classe abstract (classe MustInherit en Visual Basic).

  6. 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

  1. Ajoutez un nouveau projet nommé Calc2HVA à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.

  2. Renommez la classe Calculator.

  3. Définissez Calculator comme une classe abstract (classe MustInherit en Visual Basic).

  4. 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

  1. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur la solution CalculatorV2.

  2. Cliquez sur Ajouter, puis sur Projet existant.

  3. 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

  1. Ajoutez un nouveau projet nommé Calc2AddInSideAdapter à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.

  2. Dans l'Explorateur de solutions, ajoutez au projet Calc2AddInSideAdapter des références aux assemblys suivants :

    System.AddIn.dll

    System.AddIn.Contract.dll

  3. Ajoutez des références de projet aux projets suivants :

    Calc2AddInView

    Calc2Contract

  4. 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.

  5. Renommez la classe par défaut du projet CalculatorViewToContractAddInSideAdapter.

  6. Dans le fichier de classe, ajoutez une référence d'espace de noms à System.AddIn.Pipeline.

  7. 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.)

  8. 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

  1. Ajoutez un nouveau projet nommé Calc2V1toV2AddInSideAdapter à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.

  2. Dans l'Explorateur de solutions, ajoutez au projet Calc2V1toV2AddInSideAdapter des références aux assemblys suivants :

    System.AddIn.dll

    System.AddIn.Contract.dll

  3. Ajoutez des références de projet aux projets suivants :

    Calc1AddInView

    Calc2Contract

  4. 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.

  5. Renommez la classe par défaut du projet Calc2V1ViewToV2ContractAddInSideAdapter.

  6. Dans le fichier de classe, ajoutez une référence d'espace de noms à System.AddIn.Pipeline.

  7. 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.

  8. Appliquez l'attribut AddInAdapterAttribute à la classe Calc2V1ViewToV2ContractAddInSideAdapter, pour l'identifier comme adaptateur côté complément.

  9. 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.

  10. Ajoutez un constructeur public qui accepte un ICalculator, le met en cache dans un champ privé et appelle le constructeur de classe de base.

  11. 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

  1. Ajoutez un nouveau projet nommé Calc2HostSideAdapter à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.

  2. Dans l'Explorateur de solutions, ajoutez au projet Calc2HostSideAdapter des références aux assemblys suivants :

    System.AddIn.dll

    System.AddIn.Contract.dll

  3. Ajoutez des références de projet aux projets suivants :

    Calc2Contract

    Calc2HVA

  4. 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.

  5. Renommez la classe par défaut du projet CalculatorContractToViewHostSideAdapter.

  6. Dans le fichier de classe, ajoutez des références d'espace de noms à System.AddIn.Pipeline.

  7. 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.)

  8. Appliquez l'attribut HostAdapterAttribute à la classe CalculatorContractToViewHostSideAdapter, pour l'identifier comme adaptateur côté hôte.

  9. 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.

  10. 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.

    Remarque importanteImportant

    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.

  11. 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

  1. Ajoutez un nouveau projet nommé MathHost2 à la solution CalculatorV2. Basez-le sur le modèle Application console.

  2. Dans l'Explorateur de solutions, ajoutez au projet MathHost2 une référence à l'assembly System.AddIn.dll.

  3. 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.

  4. Renommez le fichier de classe (module en Visual Basic) MathHost2.

  5. 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.

  6. Dans le fichier de classe ou de module, ajoutez une référence d'espace de noms à System.AddIn.Hosting.

  7. 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.)

  8. 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.

  9. 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; }
            }
        }
    }
    
    RemarqueRemarque

    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

  1. Ajoutez un nouveau projet nommé AddInCalcV2 à la solution CalculatorV2. Basez-le sur le modèle Bibliothèque de classes.

  2. Dans l'Explorateur de solutions, ajoutez des références aux assemblys suivants au projet AddInCalcV2 :

    System.AddIn.dll

    System.AddIn.Contract.dll

  3. 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.

  4. Renommez le fichier de classe SampleV2AddIn.

  5. 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.

  6. 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).

  7. Appliquez l'attribut AddInAttribute à la classe SampleV2AddIn, pour identifier la classe comme un complément.

  8. 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.

  9. 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.

  10. 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

  1. 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

    RemarqueRemarque

    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.

  2. Générez la solution Visual Studio.

  3. 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.

    RemarqueRemarque

    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

  1. Assurez-vous que les deux versions du complément sont déployées.

  2. À 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.

  3. L'hôte recherche tous les compléments disponibles de son type et vous invite à sélectionner un complément. Entrez 1 ou 2.

  4. Entrez une équation pour la calculatrice, telle que 2 + 2.

  5. Tapez quitter, puis appuyez sur la touche Entrée pour fermer l'application.

  6. 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

Concepts

Spécifications du développement de pipelines

Contrats, vues et adaptateurs

Développement de pipeline