Procédure pas à pas : création d'une application extensible

Cette procédure pas à pas décrit comment créer un pipeline pour un complément qui exécute des fonctions de calculatrice simples. Elle ne fournit pas de scénario réel ; au lieu de cela, elle présente les fonctionnalités de base d'un pipeline et indique comment un complément peut fournir des services pour un hôte.

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.

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

Ce pipeline passe uniquement des types sérialisables (Double et String) entre l'hôte et le complément. Pour obtenir un exemple indiquant comment passer des collections de types de données complexes, consultez Procédure pas à pas : passage de collections entre des hôtes et des compléments.

Le contrat pour ce pipeline définit un modèle objet de quatre opérations arithmétiques : addition, soustraction, multiplication et division. L'hôte fournit au complément une équation à calculer, par exemple 2 + 2, et le complément retourne le résultat à l'hôte.

La version 2 du complément de calculatrice fournit davantage de possibilités de calcul et présente le versioning. Sa description figure dans Procédure pas à pas : activation de la compatibilité descendante lorsque votre hôte change.

RemarqueRemarque

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

Les éléments suivants sont nécessaires pour effectuer cette procédure pas à pas :

  • Visual Studio.

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é Calc1Contract. Basez-le sur le modèle Bibliothèque de classes.

  2. Nommez la solution CalculatorV1.

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 plus d'informations sur la structure du pipeline, consultez Spécifications du développement de pipelines.

Pour créer la structure de répertoires du pipeline

  1. Créez un dossier d'application à un emplacement quelconque sur votre ordinateur.

  2. Dans ce dossier, créez la structure suivante :

    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é ici uniquement pour des raisons de commodité. À l'étape appropriée, la procédure pas à pas explique comment modifier le code si la structure des dossiers de pipeline est à un emplacement différent. Consultez la description des spécifications de répertoires du pipeline dans Spécifications du développement de pipelines.

    RemarqueRemarque

    Le dossier CalcV2 n'est pas utilisé dans cette procédure pas à pas ; c'est un espace réservé pour Procédure pas à pas : activation de la compatibilité descendante lorsque votre hôte change.

Création du contrat et des vues

Le segment de contrat pour ce pipeline définit l'interface ICalc1Contract, qui définit quatre méthodes : add, subtract, multiply et divide.

Pour créer le contrat

  1. Dans la solution Visual Studio nommée CalculatorV1, ouvrez le projet Calc1Contract.

  2. Dans l'Explorateur de solutions, ajoutez au projet Calc1Contract 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. Dans l'Explorateur de solutions, 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 ICalc1Contract.

  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 ce segment de contrat. Notez que cette interface doit avoir l'attribut AddInContractAttribute.

    Imports System.AddIn.Contract
    Imports System.AddIn.Pipeline
    
    Namespace CalculatorContracts
    
        ' The AddInContractAttribute identifes this pipeline segment as a
        ' contract.
        <AddInContract()> _
        Public Interface ICalc1Contract
            Inherits IContract
    
            Function Add(ByVal a As Double, ByVal b As Double) As Double
            Function Subtract(ByVal a As Double, ByVal b As Double) As Double
            Function Multiply(ByVal a As Double, ByVal b As Double) As Double
            Function Divide(ByVal a As Double, ByVal b As Double) As Double
        End Interface
    
    End Namespace
    
    using System.AddIn.Contract;
    using System.AddIn.Pipeline;
    
    namespace CalculatorContracts
    {
        // The AddInContractAttribute identifes this pipeline segment as a 
        // contract.
        [AddInContract]
        public interface ICalc1Contract : IContract
        {
        double Add(double a, double b);
        double Subtract(double a, double b);
        double Multiply(double a, double b);
        double Divide(double a, double b);
        }
    }
    
  7. Générez éventuellement la solution Visual Studio. La solution ne peut pas être exécutée avant la dernière procédure, mais la générer après chaque procédure garantit que chaque projet est correct.

Étant donné que la vue de complément et la vue hôte du complément ont généralement le même code, en particulier dans la première version d'un complément, 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, tandis que la vue hôte du complément ne requiert aucun attribut.

Pour créer la vue de complément

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

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

  3. Dans l'Explorateur de solutions, excluez la classe par défaut ajoutée aux nouveaux projets Bibliothèque de classes et 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 ICalculator.

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

  5. Utilisez le code suivant pour terminer cette vue de complément. Notez que cette interface doit avoir l'attribut AddInBaseAttribute.

    Imports System.AddIn.Pipeline
    
    Namespace CalcAddInViews
    
        ' The AddInBaseAttribute identifes this interface as the basis for the
        ' add-in view pipeline segment.
        <AddInBaseAttribute()> _
        Public Interface ICalculator
    
            Function Add(ByVal a As Double, ByVal b As Double) As Double
            Function Subtract(ByVal a As Double, ByVal b As Double) As Double
            Function Multiply(ByVal a As Double, ByVal b As Double) As Double
            Function Divide(ByVal a As Double, ByVal b As Double) As Double
        End Interface
    
    End Namespace
    
    using System.AddIn.Pipeline;
    
    namespace CalcAddInViews 
    {
        // The AddInBaseAttribute identifes this interface as the basis for
        // the add-in view pipeline segment.
        [AddInBase()]
        public interface ICalculator 
        {
        double Add(double a, double b);
        double Subtract(double a, double b);
        double Multiply(double a, double b);
        double Divide(double a, double b);
        }
    }
    
  6. Générez éventuellement la solution Visual Studio.

Pour créer la vue hôte du complément

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

  2. Dans l'Explorateur de solutions, excluez la classe par défaut ajoutée aux nouveaux projets Bibliothèque de classes et 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 ICalculator.

  3. Dans le fichier d'interface, utilisez le code suivant pour terminer la vue hôte du complément.

    Namespace CalcHVAs
    
        Public Interface ICalculator
            Function Add(ByVal a As Double, ByVal b As Double) As Double
            Function Subtract(ByVal a As Double, ByVal b As Double) As Double
            Function Multiply(ByVal a As Double, ByVal b As Double) As Double
            Function Divide(ByVal a As Double, ByVal b As Double) As Double
        End Interface
    
    End Namespace
    
    namespace CalcHVAs 
    {
        public interface ICalculator 
        {
            double Add(double a, double b);
            double Subtract(double a, double b);
            double Multiply(double a, double b);
            double Divide(double a, double b);
        }
    }
    
  4. Générez éventuellement la solution Visual Studio.

Création de l'adaptateur côté complément

Cet adaptateur côté complément se compose d'un adaptateur de vue en contrat. Ce segment de pipeline convertit les types de la vue de complément en 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 sur le côté complément de ce pipeline.

Pour créer l'adaptateur côté complément

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

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

    System.AddIn.dll

    System.AddIn.Contract.dll

  3. Ajoutez des références de projet aux projets pour les segments de pipeline adjacents :

    Calc1AddInView

    Calc1Contract

  4. Sélectionnez chaque référence de projet, puis dans Propriétés, affectez à Copie locale la valeur False. 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 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 : CalcAddInViews et CalculatorContracts. (En Visual Basic, ces références d'espace de noms sont Calc1AddInView.CalcAddInViews et Calc1Contract.CalculatorContracts, à moins que vous ayez désactivé les espaces de noms par défaut dans vos projets Visual Basic.)

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

  9. Définissez la classe CalculatorViewToContractAddInSideAdapter pour qu'elle hérite de ContractBase, qui fournit une implémentation par défaut de l'interface IContract et implémente l'interface de contrat pour le pipeline, ICalc1Contract.

  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 ICalc1Contract, appelez simplement les membres correspondants de l'instance ICalculator qui est passée au constructeur, et retournez les résultats. Ceci adapte la vue (ICalculator) au contrat (ICalc1Contract).

    Le code suivant affiche l'adaptateur côté complément terminé.

    Imports System.AddIn.Pipeline
    Imports Calc1AddInView.CalcAddInViews
    Imports Calc1Contract.CalculatorContracts
    
    Namespace CalcAddInSideAdapters
    
        ' The AddInAdapterAttribute identifes this class as the add-in-side 
        ' adapter pipeline segment.
        <AddInAdapter()> _
        Public Class CalculatorViewToContractAddInSideAdapter
            Inherits ContractBase
            Implements ICalc1Contract
    
            Private _view As ICalculator
    
            Public Sub New(ByVal view As ICalculator)
                MyBase.New()
                _view = view
            End Sub
    
            Public Function Add(ByVal a As Double, ByVal b As Double) As Double Implements ICalc1Contract.Add
                Return _view.Add(a, b)
            End Function
    
            Public Function Subtract(ByVal a As Double, ByVal b As Double) As Double Implements ICalc1Contract.Subtract
                Return _view.Subtract(a, b)
            End Function
    
            Public Function Multiply(ByVal a As Double, ByVal b As Double) As Double Implements ICalc1Contract.Multiply
                Return _view.Multiply(a, b)
            End Function
    
            Public Function Divide(ByVal a As Double, ByVal b As Double) As Double Implements ICalc1Contract.Divide
                Return _view.Divide(a, b)
            End Function
    
        End Class
    End Namespace
    
    using System.AddIn.Pipeline;
    using CalcAddInViews;
    using CalculatorContracts;
    
    namespace CalcAddInSideAdapters 
    {
        // The AddInAdapterAttribute identifes this class as the add-in-side adapter
        // pipeline segment.
        [AddInAdapter()]
        public class CalculatorViewToContractAddInSideAdapter :
            ContractBase, ICalc1Contract 
        {
            private ICalculator _view;
    
            public CalculatorViewToContractAddInSideAdapter(ICalculator view) 
            {
                _view = view;
            }
    
            public virtual double Add(double a, double b) 
            {
                return _view.Add(a, b);
            }
    
            public virtual double Subtract(double a, double b) 
            {
                return _view.Subtract(a, b);
            }
    
            public virtual double Multiply(double a, double b) 
            {
                return _view.Multiply(a, b);
            }
    
            public virtual double Divide(double a, double b) 
            {
                return _view.Divide(a, b);
            }
        }
    }
    
  12. Générez éventuellement la solution Visual Studio.

Création de l'adaptateur côté hôte

Cet adaptateur côté hôte se compose d'un adaptateur de contrat en vue. Ce segment adapte le contrat à la vue hôte du complément.

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é Calc1HostSideAdapter à la solution CalculatorV1. Basez-le sur le modèle Bibliothèque de classes.

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

    System.AddIn.dll

    System.AddIn.Contract.dll

  3. Ajoutez des références de projet aux projets pour les segments adjacents :

    Calc1Contract

    Calc1HVA

  4. Sélectionnez chaque référence de projet, puis dans Propriétés, affectez à Copie locale la valeur False. 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 Calc1HVA.CalcHVAs et Calc1Contract.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 segment d'adaptateur côté hôte.

  9. Définissez la classe CalculatorContractToViewHostSideAdapter pour qu'elle implémente l'interface qui représente la vue hôte du complément : Calc1HVAs.ICalculator (Calc1HVA.CalcHVAs.ICalculator en Visual Basic).

  10. Ajoutez un constructeur public qui accepte le type du contrat du pipeline, ICalc1Contract. 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. Pour implémenter les membres de ICalculator, appelez simplement les membres correspondants de l'instance ICalc1Contract qui est passée au constructeur, et retournez les résultats. Ceci adapte le contrat (ICalc1Contract) à la vue (ICalculator).

    Le code suivant affiche l'adaptateur côté hôte terminé.

    Imports System.AddIn.Pipeline
    Imports Calc1Contract.CalculatorContracts
    Imports Calc1HVA.CalcHVAs
    
    Namespace CalcHostSideAdapters
    
        ' The HostAdapterAttribute identifes this class as the host-side adapter
        ' pipeline segment.
        <HostAdapterAttribute()> _
        Public Class CalculatorContractToViewHostSideAdapter
            Implements ICalculator
    
            Private _contract As ICalc1Contract
            Private _handle As System.AddIn.Pipeline.ContractHandle
    
            Public Sub New(ByVal contract As ICalc1Contract)
                    MyBase.New()
                _contract = contract
                _handle = New ContractHandle(contract)
            End Sub
    
            Public Function Add(ByVal a As Double, ByVal b As Double) As Double _
                    Implements ICalculator.Add
                Return _contract.Add(a, b)
            End Function
    
            Public Function Subtract(ByVal a As Double, ByVal b As Double) As Double _
                    Implements ICalculator.Subtract
                Return _contract.Subtract(a, b)
            End Function
    
            Public Function Multiply(ByVal a As Double, ByVal b As Double) As Double _
                    Implements ICalculator.Multiply
                Return _contract.Multiply(a, b)
            End Function
    
            Public Function Divide(ByVal a As Double, ByVal b As Double) As Double _
                    Implements ICalculator.Divide
                Return _contract.Divide(a, b)
            End Function
    
        End Class
    
    End Namespace
    
    using System.AddIn.Pipeline;
    using CalcHVAs;
    using CalculatorContracts;
    
    namespace CalcHostSideAdapters 
    {
        // The HostAdapterAttribute identifes this class as the host-side adapter
        // pipeline segment.
        [HostAdapterAttribute()]
        public class CalculatorContractToViewHostSideAdapter : ICalculator 
        {
            private ICalc1Contract _contract;
            private System.AddIn.Pipeline.ContractHandle _handle;
    
            public CalculatorContractToViewHostSideAdapter(ICalc1Contract contract) 
            {
                _contract = contract;
                _handle = new ContractHandle(contract);
            }
    
            public double Add(double a, double b) 
            {
                return _contract.Add(a, b);
            }
    
            public double Subtract(double a, double b) 
            {
                return _contract.Subtract(a, b);
            }
    
            public double Multiply(double a, double b) 
            {
                return _contract.Multiply(a, b);
            }
    
            public double Divide(double a, double b) 
            {
                return _contract.Divide(a, b);
            }
        }
    }
    
  12. Générez éventuellement la solution Visual Studio.

Création de l'hôte

Une application hôte interagit avec le complément via la vue hôte du complément. 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 :

  • Mettre à jour le cache du pipeline et les informations de complément.

  • Rechercher des compléments du type de vue hôte, ICalculator sous le répertoire racine du pipeline spécifié.

  • Inviter l'utilisateur à spécifier le complément à utiliser.

  • 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 personnalisée, qui appelle les méthodes du complément comme indiqué par la vue hôte du complément.

Pour créer l'hôte

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

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

  3. Ajoutez une référence de projet au projet Calc1HVA. Sélectionnez la référence de projet, puis dans Propriétés, affectez à Copie locale la valeur False. 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) MathHost1.

  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 Calc1HVA.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. Dans le fichier de classe ou de module, utilisez la méthode AddInStore.Update pour mettre à jour le cache. Utilisez la méthode AddInStore.FindAddIn pour obtenir une collection de jetons et utilisez la méthode AddInToken.Activate pour activer un complément.

    Le code suivant montre l'application hôte terminée.

    Imports System.Collections.Generic
    Imports System.Collections.ObjectModel
    Imports System.AddIn.Hosting
    Imports Calc1HVA.CalcHVAs
    
    Namespace MathHost
    
        Module MathHost1
    
            Sub Main()
                ' Assume that the current directory is the application folder, 
                ' and that it contains the pipeline folder structure.
                Dim addInRoot As String = Environment.CurrentDirectory & "\Pipeline"
    
                ' Update the cache files of the pipeline segments and add-ins.
                Dim warnings() As String = AddInStore.Update(addInRoot)
                For Each warning As String In warnings
                    Console.WriteLine(warning)
                Next
    
                ' Search for add-ins of type ICalculator (the host view of the add-in).
                Dim tokens As System.Collections.ObjectModel.Collection(Of AddInToken) = _
                    AddInStore.FindAddIns(GetType(ICalculator), addinRoot)
    
                ' Ask the user which add-in they would like to use.
                Dim calcToken As AddInToken = ChooseCalculator(tokens)
    
                ' Activate the selected AddInToken in a new application domain 
                ' with the Internet trust level.
                Dim calc As ICalculator = _
                    calcToken.Activate(Of ICalculator)(AddInSecurityLevel.Internet)
    
                ' Run the add-in.
                RunCalculator(calc)
            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 ICalculator)
                If IsNothing(calc) Then
                    'No calculators were found, read a line and exit.
                    Console.ReadLine()
                End If
                Console.WriteLine("Available operations: +, -, *, /")
                Console.WriteLine("Request a calculation , such as: 2 + 2")
                Console.WriteLine("Type 'exit' to exit")
                Dim line As String = Console.ReadLine
    
                While Not line.Equals("exit")
                    ' The Parser class parses the user's input.
                    Try
                        Dim c As Parser = New Parser(line)
                        Select Case (c.action)
                            Case "+"
                                Console.WriteLine(calc.Add(c.a, c.b))
                            Case "-"
                                Console.WriteLine(calc.Subtract(c.a, c.b))
                            Case "*"
                                Console.WriteLine(calc.Multiply(c.a, c.b))
                            Case "/"
                                Console.WriteLine(calc.Divide(c.a, c.b))
                            Case Else
                                Console.WriteLine("{0} is an invalid command. Valid commands are +,-,*,/", c.action)
                        End Select
                    Catch Ex As System.Exception
                        Console.WriteLine("Invalid command: {0}. Commands must be formated: [number] [operation] [number]", line)
                    End Try
                    line = Console.ReadLine
    
                End While
            End Sub
        End Module
    
        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.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";
    
                // Update the cache files of the pipeline segments and add-ins.
                string[] warnings = AddInStore.Update(addInRoot);
                foreach (string warning in warnings)
                {
                    Console.WriteLine(warning);
                }
    
                // Search for add-ins of type ICalculator (the host view of the add-in).
                Collection<AddInToken> tokens = 
                    AddInStore.FindAddIns(typeof(ICalculator), 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.
                ICalculator calc = 
                    calcToken.Activate<ICalculator>(AddInSecurityLevel.Internet);
    
                // Run the add-in.
                RunCalculator(calc);
            }
    
            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(ICalculator calc)
            {
    
                if (calc == null)
                {
                    //No calculators were found; read a line and exit.
                    Console.ReadLine();
                }
                Console.WriteLine("Available operations: +, -, *, /");
                Console.WriteLine("Request a calculation , such as: 2 + 2");
                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);
                        switch (c.Action)
                        {
                            case "+":
                                Console.WriteLine(calc.Add(c.A, c.B));
                                break;
                            case "-":
                                Console.WriteLine(calc.Subtract(c.A, c.B));
                                break;
                            case "*":
                                Console.WriteLine(calc.Multiply(c.A, c.B));
                                break;
                            case "/":
                                Console.WriteLine(calc.Divide(c.A, c.B));
                                break;
                            default:
                                Console.WriteLine("{0} is an invalid command. Valid commands are +,-,*,/", c.Action);
                                break;
                        }
                    }
                    catch
                    {
                        Console.WriteLine("Invalid command: {0}. Commands must be formated: [number] [operation] [number]", line);
                    }
    
                    line = Console.ReadLine();
                }
            }
        }
    
        internal class Parser
        {
            double a;
            double b;
            string action;
    
            internal Parser(string line)
            {
                string[] parts = line.Split(' ');
                a = double.Parse(parts[0]);
                action = parts[1];
                b = double.Parse(parts[2]);
            }
    
            public double A
            {
                get { return a; }
            }
    
            public double B
            {
                get { return b; }
            }
    
            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.

    Le code utilise une méthode ChooseCalculator pour répertorier les jetons et inviter l'utilisateur à choisir un complément. La méthode RunCalculator invite l'utilisateur à entrer des expressions mathématiques simples, analyse les expressions à l'aide de la classe Parser et affiche les résultats retournés par le complément.

  10. Générez éventuellement la solution Visual Studio.

Création du complément

Un complément implémente les méthodes spécifiées par la vue de complément. Ce complément implémente les opérations Add, Subtract, Multiply et Divide et retourne les résultats à l'hôte.

Pour créer le complément

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

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

  3. Ajoutez une référence de projet au projet Calc1AddInView. Sélectionnez la référence de projet, puis dans Propriétés, affectez à Copie locale la valeur False. En Visual Basic, utilisez l'onglet Références de Propriétés du projet pour affecter à Copie locale la valeur False pour la référence de projet.

  4. Renommez la classe AddInCalcV1.

  5. Dans le fichier de classe, ajoutez une référence d'espace de noms à System.AddIn et le segment de vue de complément : CalcAddInViews (Calc1AddInView.CalcAddInViews en Visual Basic).

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

  7. Définissez la classe AddInCalcV1 pour qu'elle implémente l'interface qui représente la vue de complément : CalcAddInViews.ICalculator (Calc1AddInView.CalcAddInViews.ICalculator en Visual Basic).

  8. Implémentez les membres de ICalculator en retournant les résultats des calculs appropriés.

    Le code suivant montre le complément terminé.

    Imports System.AddIn
    Imports Calc1AddInView.CalcAddInViews
    
    Namespace CalcAddIns
    
        ' The AddInAttribute identifies this pipeline segment as an add-in.
        <AddIn("Calculator AddIn", Version:="1.0.0.0")> _
        Public Class AddInCalcV1
            Implements ICalculator
    
            Public Function Add(ByVal a As Double, ByVal b As Double) As Double _
                    Implements ICalculator.Add
                Return (a + b)
            End Function
    
            Public Function Subtract(ByVal a As Double, ByVal b As Double) As Double _
                    Implements ICalculator.Subtract
                Return (a - b)
            End Function
    
            Public Function Multiply(ByVal a As Double, ByVal b As Double) As Double _
                    Implements ICalculator.Multiply
                Return (a * b)
            End Function
    
            Public Function Divide(ByVal a As Double, ByVal b As Double) As Double _
                    Implements ICalculator.Divide
                Return (a / b)
            End Function
        End Class
    
    End Namespace
    
    using System.Collections.Generic;
    using System.AddIn;
    using CalcAddInViews;
    
    namespace CalcAddIns
    {
        // The AddInAttribute identifies this pipeline segment as an add-in.
        [AddIn("Calculator AddIn",Version="1.0.0.0")]
        public class AddInCalcV1 : ICalculator
        {
            public double Add(double a, double b)
            {
                return a + b;
            }
    
            public double Subtract(double a, double b)
            {
                return a - b;
            }
    
            public double Multiply(double a, double b)
            {
                return a * b;
            }
    
            public double Divide(double a, double b)
            {
                return a / b;
            }
        }
    }
    
  9. Générez éventuellement la solution Visual Studio.

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

    AddInCalcV1

    MyApp\Pipeline\AddIns\CalcV1

    Calc1AddInSideAdapter

    MyApp\Pipeline\AddInSideAdapters

    Calc1AddInView

    MyApp\Pipeline\AddInViews

    Calc1Contract

    MyApp\Pipeline\Contracts

    Calc1Host

    MyApp

    Calc1HostSideAdapter

    MyApp\Pipeline\HostSideAdapters

    Calc1HVA

    MyApp

    RemarqueRemarque

    Si vous avez décidé de placer 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.Consultez la description des spécifications de répertoires du pipeline dans Spécifications du développement de pipelines.

  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 Calc1AddInView dans le projet AddInCalcV1, 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 le complément.

Pour exécuter l'application hôte

  1. À l'invite de commandes, accédez au répertoire de l'application et exécutez l'application hôte, Calc1Host.exe.

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

  3. Entrez une équation pour la calculatrice, telle que 2 + 2. Les nombres et l'opérateur doivent être séparés par un espace.

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

Voir aussi

Tâches

Procédure pas à pas : activation de la compatibilité descendante lorsque votre hôte change

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