Exemplarische Vorgehensweise: Erstellen von erweiterbaren Anwendungen

Aktualisiert: Juli 2008

Diese exemplarische Vorgehensweise beschreibt, wie eine Pipeline für ein Add-In erstellt wird, das einfache Rechnerfunktionen ausführt. Es wird kein reales Szenario dargestellt, vielmehr werden die Grundfunktionen einer Pipeline erläutert und wie ein Add-In Dienste für einen Host bereitstellen kann.

Diese exemplarische Vorgehensweise erläutert die folgenden Aufgaben:

  • Erstellen einer Visual Studio-Projektmappe

  • Erstellen der Pipelineverzeichnisstruktur

  • Erstellen des Vertrags und der Ansichten

  • Erstellen des Add-In-seitigen Adapters

  • Erstellen des hostseitigen Adapters

  • Erstellen des Hosts

  • Erstellen des Add-Ins

  • Bereitstellen der Pipeline

  • Ausführen der Hostanwendung

Diese Pipeline übergibt nur serialisierbare Typen (Double und String) zwischen dem Host und dem Add-In. Ein Beispiel, das zeigt, wie Auflistungen komplexer Datentypen übergeben werden, finden Sie unter Exemplarische Vorgehensweise: Übergeben von Auflistungen zwischen Hosts und Add-Ins.

Der Vertrag für diese Pipeline definiert ein Objektmodell aus vier arithmetischen Operationen: Addieren, Subtrahieren, Multiplizieren und Dividieren. Der Host stellt dem Add-In eine Formel zum Berechnen bereit (z. B. 2 + 2), und das Add-In gibt das Ergebnis an den Host zurück.

Version 2 des Rechner-Add-Ins stellt weitere Berechnungsmöglichkeiten bereit und veranschaulicht die Versionsverwaltung. Diese Version wird in Exemplarische Vorgehensweise: Aktivieren der Abwärtskompatibilität bei geändertem Host beschrieben.

Hinweis:

Zusätzlichen Beispielcode und Community Technology Previews von Tools für die Erstellung von Add-In-Pipelines finden Sie auf der Managed Extensibility and Add-In Framework-Website auf CodePlex.

Vorbereitungsmaßnahmen

Für diese exemplarische Vorgehensweise wird Folgendes benötigt:

  • Visual Studio.

Erstellen einer Visual Studio-Projektmappe

Verwenden Sie eine Projektmappe in Visual Studio, die die Projekte der Pipelinesegmente enthalten soll.

So erstellen Sie die Pipelineprojektmappe

  1. Erstellen Sie in Visual Studio ein neues Projekt mit dem Namen Calc1Contract. Verwenden Sie als Basis die Vorlage Klassenbibliothek.

  2. Geben Sie der Projektmappe den Namen CalculatorV1.

Erstellen der Pipelineverzeichnisstruktur

Das Add-In-Modell erfordert, dass die Pipelinesegmentassemblys in einer angegebenen Verzeichnisstruktur angeordnet werden. Weitere Informationen über die Pipelinestruktur finden Sie unter Anforderungen für die Pipelineentwicklung.

So erstellen Sie die Pipelineverzeichnisstruktur

  1. Erstellen Sie einen Anwendungsordner an einem beliebigen Ort auf dem Computer.

  2. Erstellen Sie in diesem Ordner die folgende Struktur:

    Pipeline
      AddIns
        CalcV1
        CalcV2
      AddInSideAdapters
      AddInViews
      Contracts
      HostSideAdapters
    

    Der Anwendungsordner muss nicht notwendigerweise die Struktur des Pipelineordners enthalten. Dies wird hier nur aus praktischen Gründen durchgeführt. Zu gegebener Zeit wird in dieser exemplarischen Vorgehensweise erläutert, wie der Code geändert werden muss, wenn sich die Struktur des Pipelineordners an einem anderen Speicherort befindet. Weitere Informationen finden Sie in den Ausführungen zu den Anforderungen von Pipelineverzeichnissen unter Anforderungen für die Pipelineentwicklung.

    Hinweis:

    Der Ordner CalcV2 wird in dieser exemplarischen Vorgehensweise nicht verwendet. Er dient als Platzhalter für Exemplarische Vorgehensweise: Aktivieren der Abwärtskompatibilität bei geändertem Host.

Erstellen des Vertrags und der Ansichten

Das Vertragssegment für diese Pipeline definiert die ICalc1Contract-Schnittstelle, die vier Methoden definiert: add, subtract, multiply und divide.

So erstellen Sie den Vertrag

  1. Öffnen Sie in der Visual Studio-Projektmappe CalculatorV1 das Calc1Contract-Projekt.

  2. Fügen Sie im Projektmappen-Explorer dem Calc1Contract-Projekt Verweise zu den folgenden Assemblys hinzu:

    System.AddIn.Contract.dll

    System.AddIn.dll

  3. Schließen Sie im Projektmappen-Explorer die Standardklasse aus, die neuen Klassenbibliotheksprojekten hinzugefügt wird.

  4. Fügen Sie dem Projekt im Projektmappen-Explorer mithilfe der Vorlage Schnittstelle ein neues Element hinzu. Geben Sie der Schnittstelle im Dialogfeld Neues Element hinzufügen den Namen ICalc1Contract.

  5. Fügen Sie in der Schnittstellendatei Namespaceverweise auf System.AddIn.Contract und auf System.AddIn.Pipeline hinzu.

  6. Verwenden Sie den folgenden Code, um dieses Vertragssegment zu vervollständigen. Beachten Sie, dass diese Schnittstelle das AddInContractAttribute-Attribut aufweisen muss.

    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. Optional können Sie die Visual Studio-Projektmappe erstellen. Die Projektmappe kann bis zum abschließenden Verfahren nicht ausgeführt werden. Jedoch wird durch das Erstellen im Anschluss an jedes Verfahren sichergestellt, dass jedes Projekt fehlerfrei ist.

Da für die Add-In-Ansicht und die Hostansicht des Add-Ins in der Regel derselbe Code verwendet wird (besonders in der ersten Version eines Add-Ins), können Sie die Ansichten einfach gleichzeitig erstellen. Sie unterscheiden sich lediglich in einem Aspekt: Die Add-In-Ansicht erfordert das AddInBaseAttribute-Attribut, während die Hostansicht des Add-Ins keine Attribute erfordert.

So erstellen Sie die Add-In-Ansicht

  1. Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1AddInView hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.

  2. Fügen Sie im Projektmappen-Explorer dem Calc1AddInView-Projekt einen Verweis auf System.AddIn.dll hinzu.

  3. Schließen Sie im Projektmappen-Explorer die Standardklasse aus, die neuen Klassenbibliotheksprojekten hinzugefügt wird, und fügen Sie dem Projekt mithilfe der Vorlage Schnittstelle ein neues Element hinzu. Geben Sie der Schnittstelle im Dialogfeld Neues Element hinzufügen den Namen ICalculator.

  4. Fügen Sie in der Schnittstellendatei einen Namespaceverweis auf System.AddIn.Pipeline hinzu.

  5. Verwenden Sie den folgenden Code, um diese Add-In-Ansicht zu vervollständigen. Beachten Sie, dass diese Schnittstelle das AddInBaseAttribute-Attribut aufweisen muss.

    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. Optional können Sie die Visual Studio-Projektmappe erstellen.

So erstellen Sie die Hostansicht des Add-Ins

  1. Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1HVA hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.

  2. Schließen Sie im Projektmappen-Explorer die Standardklasse aus, die neuen Klassenbibliotheksprojekten hinzugefügt wird, und fügen Sie dem Projekt mithilfe der Vorlage Schnittstelle ein neues Element hinzu. Geben Sie der Schnittstelle im Dialogfeld Neues Element hinzufügen den Namen ICalculator.

  3. Vervollständigen Sie in der Schnittstellendatei die Hostansicht des Add-Ins durch den folgenden Code.

    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. Optional können Sie die Visual Studio-Projektmappe erstellen.

Erstellen des Add-In-seitigen Adapters

Dieser Add-In-seitige Adapter besteht aus einem Ansicht-zu-Vertrag-Adapter. Dieses Pipelinesegment konvertiert die Typen von der Add-In-Ansicht in den Vertrag.

In dieser Pipeline stellt das Add-In einen Dienst für den Host bereit, und die Typen fließen vom Add-In zum Host. Da keine Typen vom Host zum Add-In fließen, müssen Sie für diese Pipeline Add-In-seitig keinen Vertrag-zu-Ansicht-Adapter aufnehmen.

So erstellen Sie den Add-In-seitigen Adapter

  1. Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1AddInSideAdapter hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.

  2. Fügen Sie im Projektmappen-Explorer dem Calc1AddInSideAdapter-Projekt Verweise auf die folgenden Assemblys hinzu:

    System.AddIn.dll

    System.AddIn.Contract.dll

  3. Fügen Sie den Projekten Projektverweise für die benachbarten Pipelinesegmente hinzu:

    Calc1AddInView

    Calc1Contract

  4. Wählen Sie alle Projektverweise aus, und legen Sie unter Eigenschaften die Option Lokale Kopie auf False fest. In Visual Basic kann unter Projekteigenschaften auf der Registerkarte Verweise die Option Lokale Kopie auf False festgelegt werden.

  5. Benennen Sie die Standardklasse des Projekts in CalculatorViewToContractAddInSideAdapter um.

  6. Fügen Sie in der Klassendatei Namespaceverweise auf System.AddIn.Pipeline hinzu.

  7. Fügen Sie in der Klassendatei Namespaceverweise für die benachbarten Segmente hinzu: CalcAddInViews und CalculatorContracts. (In Visual Basic lauten die entsprechenden Namespaceverweise Calc1AddInView.CalcAddInViews und Calc1Contract.CalculatorContracts, sofern der Standardnamespace für Visual Basic-Projekte nicht deaktiviert wurde.)

  8. Wenden Sie das AddInAdapterAttribute-Attribut auf die CalculatorViewToContractAddInSideAdapter-Klasse an, um sie als Add-In-seitigen Adapter zu definieren.

  9. Lassen Sie die CalculatorViewToContractAddInSideAdapter-Klasse ContractBase erben, die eine Standardimplementierung der IContract-Schnittstelle bereitstellt, und implementieren Sie die Vertragsschnittstelle für die Pipeline (ICalc1Contract).

  10. Fügen Sie einen öffentlichen Konstruktor hinzu, der einen ICalculator akzeptiert, diesen in einem privaten Feld zwischenspeichert und den Basisklassenkonstruktor aufruft.

  11. Um die Member von ICalc1Contract zu implementieren, rufen Sie einfach die entsprechenden Member der ICalculator-Instanz auf, die dem Konstruktor übergeben wird, und geben Sie die Ergebnisse zurück. Dadurch wird die Ansicht (ICalculator) an den Vertrag (ICalc1Contract) angepasst.

    Im folgenden Code wird der vollständige Add-In-seitige Adapter dargestellt.

    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. Optional können Sie die Visual Studio-Projektmappe erstellen.

Erstellen des hostseitigen Adapters

Dieser hostseitige Adapter besteht aus einem Vertrag-zu-Ansicht-Adapter. Mit diesem Segment wird der Vertrag an die Hostansicht des Add-Ins angepasst.

In dieser Pipeline stellt das Add-In einen Dienst für den Host bereit, und die Typen fließen vom Add-In zum Host. Da keine Typen vom Host zum Add-In fließen, müssen Sie keinen Vertrag-zu-Ansicht-Adapter aufnehmen.

Zum Implementieren der Verwaltung der Lebensdauer verwenden Sie ein ContractHandle-Objekt, um ein Lebensdauertoken an den Vertrag anzufügen. Sie müssen einen Verweis auf dieses Handle verwenden, damit die Verwaltung der Lebensdauer funktioniert. Nach Anwendung des Tokens ist keine zusätzliche Programmierung erforderlich, da das Add-In-System Objekte entfernen kann, die nicht mehr verwendet werden, und diese Objekte für die Garbage Collection verfügbar macht. Weitere Informationen finden Sie unter Verwaltung der Lebensdauer.

So erstellen Sie den hostseitigen Adapter

  1. Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1HostInSideAdapter hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.

  2. Fügen Sie im Projektmappen-Explorer dem Calc1HostSideAdapter-Projekt Verweise auf die folgenden Assemblys hinzu:

    System.AddIn.dll

    System.AddIn.Contract.dll

  3. Fügen Sie den Projekten Projektverweise für die benachbarten Segmente hinzu:

    Calc1Contract

    Calc1HVA

  4. Wählen Sie alle Projektverweise aus, und legen Sie unter Eigenschaften die Option Lokale Kopie auf False fest. In Visual Basic kann unter Projekteigenschaften auf der Registerkarte Verweise die Option Lokale Kopie auf False festgelegt werden.

  5. Benennen Sie die Standardklasse des Projekts in CalculatorContractToViewHostSideAdapter um.

  6. Fügen Sie in der Klassendatei Namespaceverweise auf System.AddIn.Pipeline hinzu.

  7. Fügen Sie in der Klassendatei Namespaceverweise für die benachbarten Segmente hinzu: CalcHVAs und CalculatorContracts. (In Visual Basic lauten die entsprechenden Namespaceverweise Calc1HVA.CalcHVAs und Calc1Contract.CalculatorContracts, sofern der Standardnamespace für Visual Basic-Projekte nicht deaktiviert wurde.)

  8. Wenden Sie das HostAdapterAttribute-Attribut auf die CalculatorContractToViewHostSideAdapter-Klasse an, um sie als hostseitiges Adaptersegment zu kennzeichnen.

  9. Implementieren Sie mit der CalculatorContractToViewHostSideAdapter-Klasse die Schnittstelle, die die Host-Ansicht des Add-Ins darstellt: Calc1HVAs.ICalculator (Calc1HVA.CalcHVAs.ICalculator in Visual Basic).

  10. Fügen Sie einen öffentlichen Konstruktor hinzu, der den Pipelinevertragstyp ICalc1Contract akzeptiert. Der Konstruktor muss den Verweis auf den Vertrag zwischenspeichern. Der Konstruktor muss außerdem einen neuen ContractHandle für den Vertrag erstellen und zwischenspeichern, um die Lebensdauer des Add-Ins zu verwalten.

    Wichtiger Hinweis:

    Das ContractHandle ist für die Lebensdauerverwaltung entscheidend. Wenn Sie keinen Verweis auf das ContractHandle-Objekt beibehalten, wird es von der Garbage Collection freigegeben, und die Pipeline wird zu einem für das Programm unerwarteten Zeitpunkt beendet. Dies kann zu Fehlern führen, die schwierig zu diagnostizieren sind, z. B. AppDomainUnloadedException. Das Herunterfahren ist eine normale Phase im Lebenszyklus einer Pipeline, es gibt daher keine Möglichkeit für den Code zum Verwalten des Lebenszyklus festzustellen, dass es sich bei dem Zustand um einen Fehler handelt.

  11. Um die Member von ICalculator zu implementieren, rufen Sie einfach die entsprechenden Member der ICalc1Contract-Instanz auf, die dem Konstruktor übergeben wird, und geben Sie die Ergebnisse zurück. Dadurch wird der Vertrag (ICalc1Contract) an die Ansicht (ICalculator) angepasst.

    Im folgenden Code wird der vollständige hostseitige Adapter dargestellt.

    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. Optional können Sie die Visual Studio-Projektmappe erstellen.

Erstellen des Hosts

Eine Hostanwendung interagiert durch die Hostansicht des Add-Ins mit dem Add-In. Sie verwendet Methoden zur Add-In-Erkennung und -Aktivierung, die durch die AddInStore-Klasse und die AddInToken-Klasse bereitgestellt werden, um folgende Aktionen auszuführen:

  • Aktualisieren des Caches der Pipeline- und Add-In-Informationen

  • Suchen von Add-Ins vom Hostansichtstyp ICalculator unter dem angegebenen Pipelinestammverzeichnis.

  • Auffordern des Benutzers zur Angabe, welches Add-In verwendet werden soll

  • Aktivieren des ausgewählten Add-Ins mit einer angegebenen Sicherheitsvertrauensebene in einer neuen Anwendungsdomäne

  • Ausführen der angepassten RunCalculator-Methode, die die Methoden des Add-Ins gemäß den Angaben in der Hostansicht des Add-Ins aufruft

So erstellen Sie den Host

  1. Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1Host hinzu. Verwenden Sie die Konsolenanwendungsvorlage als Grundlage.

  2. Fügen Sie im Projektmappen-Explorer dem Calc1Host-Projekt einen Verweis auf die System.AddIn.dll-Assembly hinzu.

  3. Fügen Sie dem Calc1HVA-Projekt einen Projektverweis hinzu. Wählen Sie den Projektverweis aus, und legen Sie unter Eigenschaften die Option Lokale Kopie auf False fest. In Visual Basic kann unter Projekteigenschaften auf der Registerkarte Verweise die Option Lokale Kopie auf False festgelegt werden.

  4. Benennen Sie die Klassendatei (Modul in Visual Basic) in MathHost1 um.

  5. Verwenden Sie in Visual Basic im Dialogfeld Projekteigenschaften die Registerkarte Anwendung, um das Startobjekt auf Sub Main festzulegen.

  6. Fügen Sie in der Klassen- oder Moduldatei einen Namespaceverweis auf System.AddIn.Hosting hinzu.

  7. Fügen Sie in der Klassen- oder Moduldatei den Namespaceverweis CalcHVAs für die Hostansicht des Add-Ins hinzu. (In Visual Basic lautet der entsprechende Namespaceverweis Calc1HVA.CalcHVAs, sofern der Standardnamespace für Visual Basic-Projekte nicht deaktiviert wurde.)

  8. Wählen Sie die Projektmappe im Projektmappen-Explorer aus, und wählen Sie Eigenschaften aus dem Menü Projekt. Legen Sie im Dialogfeld Projektmappen-Eigenschaftenseiten die Option Einzelnes Startprojekt als Hostanwendungsprojekt fest.

  9. Aktualisieren Sie den Cache in der Klassen- oder Moduldatei mithilfe der AddInStore.Update-Methode. Rufen Sie mit der AddInStore.FindAddIn-Methode eine Auflistung von Tokens ab, und aktivieren Sie mit der AddInToken.Activate-Methode ein Add-In.

    Im folgenden Code wird die vollständige Hostanwendung dargestellt.

    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; }
            }
        }
    }
    
    Hinweis:

    Bei diesem Codebeispiel wird davon ausgegangen, dass sich die Pipelineordnerstruktur im Anwendungsordner befindet. Wenn sie sich an einem anderen Speicherort befindet, ändern Sie die Codezeile, mit der die addInRoot-Variable festgelegt wird, damit die Variable den Pfad zur Pipelineverzeichnisstruktur enthält.

    Im Code wird die ChooseCalculator-Methode verwendet, um die Token aufzulisten und den Benutzer aufzufordern, ein Add-In auszuwählen. Mit der RunCalculator-Methode wird der Benutzer aufgefordert, einfache mathematische Ausdrücke einzugeben, werden die Ausdrücke mithilfe der Parser-Klasse analysiert und die zurückgegebenen Ergebnisse durch das Add-In angezeigt.

  10. Optional können Sie die Visual Studio-Projektmappe erstellen.

Erstellen des Add-Ins

Ein Add-In implementiert die von der Add-In-Ansicht angegebenen Methoden. Dieses Add-In implementiert die Operationen Add, Subtract, Multiply und Divide und gibt die Ergebnisse an den Host zurück.

So erstellen Sie das Add-In

  1. Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen AddInCalcV1 hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.

  2. Fügen Sie im Projektmappen-Explorer dem Projekt einen Verweis auf die System.AddIn.dll-Assembly hinzu.

  3. Fügen Sie einen Projektverweis auf das Projekt Calc1AddInView hinzu. Wählen Sie den Projektverweis aus, und legen Sie unter Eigenschaften die Option Lokale Kopie auf False fest. In Visual Basic kann unter Projekteigenschaften auf der Registerkarte Verweise die Option Lokale Kopie für den Projektverweis auf False festgelegt werden.

  4. Benennen Sie die Klasse AddInCalcV1 um.

  5. Fügen Sie in der Klassendatei einen Namespaceverweis auf System.AddIn und das Add-In-Ansichtssegment hinzu: CalcAddInViews (Calc1AddInView.CalcAddInViews in Visual Basic).

  6. Wenden Sie das AddInAttribute-Attribut auf die AddInCalcV1-Klasse an, um die Klasse als Add-In zu kennzeichnen.

  7. Implementieren Sie mit der AddInCalcV1-Klasse die Schnittstelle, die die Add-In-Ansicht darstellt: CalcAddInViews.ICalculator (Calc1AddInView.CalcAddInViews.ICalculator in Visual Basic).

  8. Implementieren Sie die Member von ICalculator, indem Sie die Ergebnisse der entsprechenden Berechnungen zurückgeben.

    Mit dem folgenden Code wird das vollständige Add-In dargestellt.

    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. Optional können Sie die Visual Studio-Projektmappe erstellen.

Bereitstellen der Pipeline

Sie können jetzt die Add-In-Segmente für die erforderliche Pipelineverzeichnisstruktur erstellen und bereitstellen.

So stellen Sie die Segmente in der Pipeline bereit

  1. Legen Sie für jedes Projekt der Projektmappe in den Projekteigenschaften auf der Registerkarte Build (der Registerkarte Kompilieren in Visual Basic) den Wert des Ausgabepfads (des Buildausgabepfads in Visual Basic) fest. Wenn Sie den Anwendungsordner beispielsweise MyApp genannt haben, werden Buildvorgänge der Projekte in den folgenden Ordnern durchgeführt:

    Projekt

    Pfad

    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

    Hinweis:

    Wenn für die Pipelineordnerstruktur ein anderer Speicherort als der Anwendungsordner verwendet wird, müssen die in der Tabelle angezeigten Pfade entsprechend angepasst werden. Weitere Informationen finden Sie in den Ausführungen zu den Anforderungen von Pipelineverzeichnissen unter Anforderungen für die Pipelineentwicklung.

  2. Erstellen Sie die Visual Studio-Projektmappe.

  3. Überprüfen Sie die Anwendungs- und Pipelineverzeichnisse, um sicherzustellen, dass die Assemblys in die richtigen Verzeichnisse kopiert und keine zusätzlichen Kopien der Assemblys in falschen Ordnern erstellt wurden.

    Hinweis:

    Wenn im AddInCalcV1-Projekt für den Calc1AddInView-Projektverweis die Option Lokale Kopie nicht auf False festgelegt wurde, kann das Add-In aufgrund von Kontextproblemen vom Ladeprogramm nicht gefunden werden.

    Informationen zum Bereitstellen in der Pipeline finden Sie unter Anforderungen für die Pipelineentwicklung.

Ausführen der Hostanwendung

Sie können jetzt den Host ausführen und mit dem Add-In interagieren.

So führen Sie die Hostanwendung aus

  1. Navigieren Sie an der Eingabeaufforderung zum Anwendungsverzeichnis, und führen Sie die Hostanwendung Calc1Host.exe aus.

  2. Der Host sucht alle verfügbaren Add-Ins von seinem Typ und fordert Sie auf, ein Add-In auszuwählen. Geben Sie 1 für das einzige verfügbare Add-In ein.

  3. Geben Sie eine Formel für den Rechner ein, z. B. 2 + 2. Zwischen den Zahlen und dem Operator müssen sich Leerzeichen befinden.

  4. Geben Sie exit ein, und drücken Sie die EINGABETASTE, um die Anwendung zu schließen.

Siehe auch

Aufgaben

Exemplarische Vorgehensweise: Aktivieren der Abwärtskompatibilität bei geändertem Host

Exemplarische Vorgehensweise: Übergeben von Auflistungen zwischen Hosts und Add-Ins

Konzepte

Anforderungen für die Pipelineentwicklung

Verträge, Ansichten und Adapter

Pipeline-Entwicklung

Änderungsprotokoll

Date

Versionsgeschichte

Grund

Juli 2008

Fehler im Text korrigiert. Hinweis zum Beibehalten eines Verweises auf den Vertrag hinzugefügt.

Kundenfeedback.