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
Erstellen Sie in Visual Studio ein neues Projekt mit dem Namen Calc1Contract. Verwenden Sie als Basis die Vorlage Klassenbibliothek.
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
Erstellen Sie einen Anwendungsordner an einem beliebigen Ort auf dem Computer.
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
Öffnen Sie in der Visual Studio-Projektmappe CalculatorV1 das Calc1Contract-Projekt.
Fügen Sie im Projektmappen-Explorer dem Calc1Contract-Projekt Verweise zu den folgenden Assemblys hinzu:
System.AddIn.Contract.dll
System.AddIn.dll
Schließen Sie im Projektmappen-Explorer die Standardklasse aus, die neuen Klassenbibliotheksprojekten hinzugefügt wird.
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.
Fügen Sie in der Schnittstellendatei Namespaceverweise auf System.AddIn.Contract und auf System.AddIn.Pipeline hinzu.
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); } }
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
Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1AddInView hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Calc1AddInView-Projekt einen Verweis auf System.AddIn.dll hinzu.
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.
Fügen Sie in der Schnittstellendatei einen Namespaceverweis auf System.AddIn.Pipeline hinzu.
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); } }
Optional können Sie die Visual Studio-Projektmappe erstellen.
So erstellen Sie die Hostansicht des Add-Ins
Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1HVA hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
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.
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); } }
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
Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1AddInSideAdapter hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Calc1AddInSideAdapter-Projekt Verweise auf die folgenden Assemblys hinzu:
System.AddIn.dll
System.AddIn.Contract.dll
Fügen Sie den Projekten Projektverweise für die benachbarten Pipelinesegmente hinzu:
Calc1AddInView
Calc1Contract
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.
Benennen Sie die Standardklasse des Projekts in CalculatorViewToContractAddInSideAdapter um.
Fügen Sie in der Klassendatei Namespaceverweise auf System.AddIn.Pipeline hinzu.
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.)
Wenden Sie das AddInAdapterAttribute-Attribut auf die CalculatorViewToContractAddInSideAdapter-Klasse an, um sie als Add-In-seitigen Adapter zu definieren.
Lassen Sie die CalculatorViewToContractAddInSideAdapter-Klasse ContractBase erben, die eine Standardimplementierung der IContract-Schnittstelle bereitstellt, und implementieren Sie die Vertragsschnittstelle für die Pipeline (ICalc1Contract).
Fügen Sie einen öffentlichen Konstruktor hinzu, der einen ICalculator akzeptiert, diesen in einem privaten Feld zwischenspeichert und den Basisklassenkonstruktor aufruft.
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); } } }
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
Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1HostInSideAdapter hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Calc1HostSideAdapter-Projekt Verweise auf die folgenden Assemblys hinzu:
System.AddIn.dll
System.AddIn.Contract.dll
Fügen Sie den Projekten Projektverweise für die benachbarten Segmente hinzu:
Calc1Contract
Calc1HVA
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.
Benennen Sie die Standardklasse des Projekts in CalculatorContractToViewHostSideAdapter um.
Fügen Sie in der Klassendatei Namespaceverweise auf System.AddIn.Pipeline hinzu.
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.)
Wenden Sie das HostAdapterAttribute-Attribut auf die CalculatorContractToViewHostSideAdapter-Klasse an, um sie als hostseitiges Adaptersegment zu kennzeichnen.
Implementieren Sie mit der CalculatorContractToViewHostSideAdapter-Klasse die Schnittstelle, die die Host-Ansicht des Add-Ins darstellt: Calc1HVAs.ICalculator (Calc1HVA.CalcHVAs.ICalculator in Visual Basic).
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.
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); } } }
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
Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen Calc1Host hinzu. Verwenden Sie die Konsolenanwendungsvorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Calc1Host-Projekt einen Verweis auf die System.AddIn.dll-Assembly hinzu.
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.
Benennen Sie die Klassendatei (Modul in Visual Basic) in MathHost1 um.
Verwenden Sie in Visual Basic im Dialogfeld Projekteigenschaften die Registerkarte Anwendung, um das Startobjekt auf Sub Main festzulegen.
Fügen Sie in der Klassen- oder Moduldatei einen Namespaceverweis auf System.AddIn.Hosting hinzu.
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.)
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.
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.
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
Fügen Sie der CalculatorV1-Projektmappe ein neues Projekt mit dem Namen AddInCalcV1 hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Projekt einen Verweis auf die System.AddIn.dll-Assembly hinzu.
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.
Benennen Sie die Klasse AddInCalcV1 um.
Fügen Sie in der Klassendatei einen Namespaceverweis auf System.AddIn und das Add-In-Ansichtssegment hinzu: CalcAddInViews (Calc1AddInView.CalcAddInViews in Visual Basic).
Wenden Sie das AddInAttribute-Attribut auf die AddInCalcV1-Klasse an, um die Klasse als Add-In zu kennzeichnen.
Implementieren Sie mit der AddInCalcV1-Klasse die Schnittstelle, die die Add-In-Ansicht darstellt: CalcAddInViews.ICalculator (Calc1AddInView.CalcAddInViews.ICalculator in Visual Basic).
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; } } }
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
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.
Erstellen Sie die Visual Studio-Projektmappe.
Ü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
Navigieren Sie an der Eingabeaufforderung zum Anwendungsverzeichnis, und führen Sie die Hostanwendung Calc1Host.exe aus.
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.
Geben Sie eine Formel für den Rechner ein, z. B. 2 + 2. Zwischen den Zahlen und dem Operator müssen sich Leerzeichen befinden.
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
Änderungsprotokoll
Date |
Versionsgeschichte |
Grund |
---|---|---|
Juli 2008 |
Fehler im Text korrigiert. Hinweis zum Beibehalten eines Verweises auf den Vertrag hinzugefügt. |
Kundenfeedback. |