Exemplarische Vorgehensweise: Aktivieren der Abwärtskompatibilität bei geändertem Host
Aktualisiert: Juli 2008
Diese exemplarische Vorgehensweise beschreibt Version 2 der Pipeline, die in Exemplarische Vorgehensweise: Erstellen von erweiterbaren Anwendungen beschrieben wird. Version 2 enthält zusätzliche Berechnungsfunktionen, indem eine durch Trennzeichen getrennte Zeichenfolge arithmetischer Operationen mit Unterstützung für den Host bereitgestellt wird. Der Host kann dann eine Operation auswählen und eine Formel zur Berechnung durch das Add-In übermitteln.
Die Pipeline weist einen neuen Host und einen neuen Vertrag auf. Damit Version 1 des Add-Ins mit einem neuen Host und Vertrag funktioniert, enthält die Pipeline die für Version 1 verwendete Add-In-Ansicht sowie einen Add-In-seitigen Adapter, der die Daten aus der älteren Add-In-Ansicht in den neuen Vertrag umwandelt. In der folgenden Abbildung wird verdeutlicht, wie beide Add-Ins mit demselben Host zusammenarbeiten können.
Neuer Host, alte Add-Ins
Diese Pipeline wird auch in Szenarien für Add-In-Pipelines beschrieben.
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, der Adapter für die neue Add-In-Version und für das Add-In aus Version 1 enthält.
Erstellen des hostseitigen Adapters
Erstellen des Hosts
Erstellen des Add-Ins
Bereitstellen der Pipeline
Ausführen der Hostanwendung
Außerdem wird die Verwendung abstrakter Basisklassen zum Definieren von Ansichten veranschaulicht. Es wird gezeigt, dass diese Ansichten kompatibel zu Ansichten sind, die durch Schnittstellen definiert werden. Es wird empfohlen, Schnittstellen zu verwenden.
Hinweis: |
---|
Ein Teil des Codes, der in dieser exemplarischen Vorgehensweise verwendet wird, enthält externe Namespaceverweise. Die Schritte der exemplarischen Vorgehensweise entsprechen genau den Verweisen, die in Visual Studio erforderlich sind. |
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
Zum Durchführen dieser exemplarischen Vorgehensweise benötigen Sie die folgenden Komponenten:
Visual Studio.
Die unter Exemplarische Vorgehensweise: Erstellen von erweiterbaren Anwendungen beschriebene Pipeline der Version 1. Da Version 2 Pipelinesegmente verwendet, die in Version 1 entwickelt wurden, müssen Sie die Pipeline der Version 1 entwickeln und bereitstellen, bevor Sie die Schritte in diesem Thema ausführen.
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 Calc2Contract. Verwenden Sie als Basis die Vorlage Klassenbibliothek.
Geben Sie der Projektmappe den Namen CalculatorV2.
Erstellen der Pipelineverzeichnisstruktur
Das Add-In-Modell erfordert, dass die Pipelinesegmentassemblys in einer angegebenen Verzeichnisstruktur angeordnet werden.
So erstellen Sie die Pipelineverzeichnisstruktur
Wenn Sie dies noch nicht getan haben, fügen Sie den Ordner CalcV2 zur Pipelineordnerstruktur hinzu, die Sie in der Exemplarische Vorgehensweise: Erstellen von erweiterbaren Anwendungen erstellt haben. Der Ordner CalcV2 enthält die neue Version des Add-Ins.
Pipeline AddIns CalcV1 CalcV2 AddInSideAdapters AddInViews Contracts HostSideAdapters
Der Anwendungsordner muss nicht notwendigerweise die Struktur des Pipelineordners aufweisen. Dies wird in diesen exemplarischen Vorgehensweisen nur aus praktischen Gründen durchgeführt. Wenn Sie in der ersten exemplarischen Vorgehensweise die Struktur des Pipelineordners in einem anderen Speicherort gespeichert haben, gehen Sie in dieser exemplarischen Vorgehensweise entsprechend vor. Weitere Informationen finden Sie in den Ausführungen zu den Anforderungen von Pipelineverzeichnissen unter Anforderungen für die Pipelineentwicklung.
Erstellen des Vertrags und der Ansichten
Das Vertragssegment für diese Pipeline definiert die ICalc2Contract-Schnittstelle, die die folgenden beiden Methoden enthält:
Die GetAvailableOperations-Methode
Diese Methode gibt eine Zeichenfolge der mathematischen Operationen zurück, die das Add-In für den Host unterstützt. Version 2 unterstützt fünf Operationen, und diese Methode gibt die Zeichenfolge "+,-,*,/,**" zurück, wobei "**" die Pow-Operation darstellt.
In der Add-In-Ansicht und der Hostansicht hat diese Methode die Bezeichnung Operations anstelle von GetAvailableOperations.
Sie können Methoden im Vertrag als Eigenschaften für die Ansichten verfügbar machen, indem Sie den Methodenaufruf in eine Eigenschaft im Adapter umwandeln.
Die Operate-Methode
Der Host ruft diese Methode auf, um eine Formel für das Add-In bereitzustellen, sodass das Add-In die Berechnung ausführen und das Ergebnis zurückgeben kann.
So erstellen Sie den Vertrag
Öffnen Sie in der Visual Studio-Projektmappe CalculatorV2 das Calc2Contract-Projekt.
Fügen Sie im Projektmappen-Explorer Verweise auf die folgenden Assemblys dem Calc2Contract-Projekt 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 mit der Schnittstelle-Vorlage ein neues Element hinzu. Geben Sie der Schnittstelle im Dialogfeld Neues Element hinzufügen den Namen ICalc2Contract.
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 fertig zu stellen. Beachten Sie, dass diese Schnittstelle das AddInContractAttribute-Attribut aufweisen muss.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Contract Imports System.AddIn.Pipeline Namespace CalculatorContracts <AddInContract()> _ Public Interface ICalc2Contract Inherits IContract Function GetAvailableOperations() As String Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double End Interface End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn.Contract; using System.AddIn.Pipeline; namespace CalculatorContracts { [AddInContract] public interface ICalc2Contract : IContract { string GetAvailableOperations(); double Operate(String operation, double a, double b); } }
Da die Add-In-Ansicht und die Hostansicht denselben Code enthalten, können Sie die Ansichten mühelos zur selben Zeit 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ür Version 2
Fügen Sie der CalculatorV2-Projektmappe ein neues Projekt mit dem Namen Calc2AddInView hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Calc2AddInView-Projekt einen Verweis auf System.AddIn.dll hinzu.
Benennen Sie die Klasse in Calculator2 um.
Fügen Sie in der Klassendatei einen Namespaceverweis auf System.AddIn.Pipeline hinzu.
Legen Sie Calculator2 als abstract-Klasse fest (MustInherit-Klasse in Visual Basic).
Verwenden Sie den folgenden Code für diese Add-In-Ansicht. Beachten Sie, dass diese Klasse das AddInBaseAttribute-Attribut aufweisen muss.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Pipeline Namespace CalcAddInViews <AddInBase()> _ Public MustInherit Class Calculator2 Public MustOverride ReadOnly Property Operations() As String Public MustOverride Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double End Class End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn.Pipeline; namespace CalcAddInViews { [AddInBase] public abstract class Calculator2 { public abstract string Operations { get; } public abstract double Operate(string operation, double a, double b); } }
So erstellen Sie die Hostansicht des Add-Ins
Fügen Sie der CalculatorV2-Projektmappe ein neues Projekt mit dem Namen Calc2HVA hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Benennen Sie die Klasse in Calculator um.
Legen Sie Calculator als abstract-Klasse fest (MustInherit-Klasse in Visual Basic).
Verwenden Sie in der Klassendatei den folgenden Code, um die Hostansicht des Add-Ins zu erstellen.
Imports Microsoft.VisualBasic Imports System Namespace CalcHVAs Public MustInherit Class Calculator Public MustOverride ReadOnly Property Operations() As String Public MustOverride Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double End Class End Namespace
namespace CalcHVAs { public abstract class Calculator { public abstract string Operations { get; } public abstract double Operate(string operation, double a, double b); } }
Um die Verwendung von Version 1 des Add-Ins mit dem neuen Host zu veranschaulichen, muss die Projektmappe die Add-In-Ansicht, die für Version 1 des Rechner-Add-Ins erstellt wurde, enthalten.
So fügen Sie das Add-In-Ansichtsprojekt aus Version 1 hinzu
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die CalculatorV2-Projektmappe.
Klicken Sie auf Hinzufügen und dann auf Vorhandenes Projekt.
Gehen Sie zu den Ordnern, die die CalculatorV1-Projektmappe enthalten, und wählen Sie die Projektdatei für das Calc1AddInView-Projekt aus.
Erstellen des Add-In-seitigen Adapters
Dieser Add-In-seitige Adapter besteht aus zwei Ansicht-zu-Vertrag-Adaptern: Ein Adapter dient zum Anpassen von Version 2 der Add-In-Ansicht an Version 2 des Vertrags, der andere Adapter dient zum Anpassen von Version 1 der Add-In-Ansicht an Version 2 des Vertrags.
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 Ansicht-zu-Vertrag-Adapter aufnehmen.
So erstellen Sie den Add-In-seitigen Adapter
Fügen Sie der Projektmappe CalculatorV2 ein neues Projekt mit dem Namen Calc2AddInSideAdapter hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Calc2AddInSideAdapter-Projekt Verweise auf die folgenden Assemblys hinzu:
System.AddIn.dll
System.AddIn.Contract.dll
Fügen Sie den folgenden Projekten Projektverweise hinzu:
Calc2AddInView
Calc2Contract
Wählen Sie die einzelnen Projektverweise aus, und legen Sie unter Eigenschaften die Option Lokale Kopie auf False fest, damit die Assemblys, auf die verwiesen wird, nicht in den lokalen Buildordner kopiert werden. Die Assemblys befinden sich, wie weiter unten in "Bereitstellen der Pipeline" beschrieben, im Pipelineverzeichnis. 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 einen Namespaceverweis 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 Calc2AddInView.CalcAddInViews und Calc2Contract.CalculatorContracts, sofern der Standardnamespace für Visual Basic-Projekte nicht deaktiviert wurde.)
Verwenden Sie den folgenden Code für diesen Add-In-seitigen Adapter. Das Implementierungsmuster ähnelt dem Add-In-seitigen Adapter für Version 1, obwohl die Vertragsschnittstelle erheblich abweicht.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Pipeline Imports System.AddIn.Contract Imports Calc2Contract.CalculatorContracts Imports Calc2AddInView.CalcAddInViews Namespace CalculatorContractsAddInAdapters <AddInAdapterAttribute()> _ Public Class CalculatorViewToContractAddInAdapter Inherits ContractBase Implements ICalc2Contract Private _view As Calculator2 Public Sub New(ByVal calculator As Calculator2) _view = calculator End Sub Public Function GetAvailableOperations() As String Implements ICalc2Contract.GetAvailableOperations Return _view.Operations End Function Public Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double Implements ICalc2Contract.Operate Return _view.Operate(operation, a, b) End Function End Class End Namespace
using System.AddIn.Pipeline; using CalcAddInViews; using CalculatorContracts; namespace CalcAddInSideAdapters { [AddInAdapterAttribute] public class CalculatorViewToContractAddInAdapter : ContractBase, ICalc2Contract { private Calculator2 _view; public CalculatorViewToContractAddInAdapter(Calculator2 calculator) { _view = calculator; } public string GetAvailableOperations() { return _view.Operations; } public double Operate(string operation, double a, double b) { return _view.Operate(operation, a, b); } } }
Damit Version 1 des Add-Ins mit dem neuen Host kommunizieren kann, erfordert die Pipeline für Version 1 des Add-Ins einen Add-In-seitigen Adapter, der die Daten aus der alten Add-In-Ansicht in den neuen Vertrag umwandelt.
So erstellen Sie den Add-In-seitigen Adapter für die Umwandlung aus Version 1 in Version 2
Fügen Sie der CalculatorV2-Projektmappe ein neues Projekt mit dem Namen Calc2V1toV2AddInSideAdapter hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Calc2V1toV2AddInSideAdapter-Projekt Verweise auf die folgenden Assemblys hinzu:
System.AddIn.dll
System.AddIn.Contract.dll
Fügen Sie den folgenden Projekten Projektverweise hinzu:
Calc1AddInView
Calc2Contract
Wählen Sie die einzelnen Projektverweise aus, und legen Sie unter Eigenschaften die Option Lokale Kopie auf False fest, damit die Assemblys, auf die verwiesen wird, nicht in den lokalen Buildordner kopiert werden. 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 Calc2V1ViewToV2ContractAddInSideAdapter um.
Fügen Sie in der Klassendatei einen Namespaceverweis 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 Calc2Contract.CalculatorContracts, sofern der Standardnamespace für Visual Basic-Projekte nicht deaktiviert wurde.) Beachten Sie, dass der Namespace der Ansicht von Version 1 und der Vertrag von Version 2 stammt.
Wenden Sie das AddInAdapterAttribute-Attribut auf die Calc2V1ViewToV2ContractAddInSideAdapter-Klasse an, um sie als den Add-In-seitigen Adapter zu definieren.
Lassen Sie die Calc2V1ViewToV2ContractAddInSideAdapter-Klasse von ContractBase erben, um eine Standardimplementierung der IContract-Schnittstelle bereitzustellen, und implementieren Sie Version 2 der Vertragsschnittstelle für die Pipeline (ICalc2Contract).
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 ICalc2Contract zu implementieren, müssen Sie die entsprechenden Member der ICalculator-Instanz aufrufen, die dem Konstruktor übergeben wird, und die Ergebnisse zurückgeben. Aufgrund der Unterschiede zwischen Version 1 und Version 2 der Vertragsschnittstellen benötigen Sie eine switch-Anweisung (Select Case-Anweisung in Visual Basic), um die Ansicht (ICalculator) an den Vertrag (ICalc2Contract) anzupassen.
Im folgenden Code wird der vollständige Add-In-seitige Adapter dargestellt.
Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Pipeline Imports Calc1AddInView.CalcAddInViews Imports Calc2Contract.CalculatorContracts Namespace AddInSideV1toV2Adapter <AddInAdapter()> _ Public Class Calc2V1ViewToV2ContractAddInSideAdapter Inherits ContractBase Implements ICalc2Contract Private _view As ICalculator Public Sub New(ByVal calc As ICalculator) MyBase.New() _view = calc End Sub Public Function GetAvailableOperations() As String Implements ICalc2Contract.GetAvailableOperations Return "+, -, *, /" End Function Public Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) _ As Double Implements ICalc2Contract.Operate Select Case (operation) Case "+" Return _view.Add(a, b) Case "-" Return _view.Subtract(a, b) Case "*" Return _view.Multiply(a, b) Case "/" Return _view.Divide(a, b) Case Else Throw New InvalidOperationException(("This add-in does not support: " + operation)) End Select End Function End Class End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn.Pipeline; using CalcAddInViews; using CalculatorContracts; namespace AddInSideV1toV2Adapter { [AddInAdapter] public class Calc2V1ViewToV2ContractAddInSideAdapter : ContractBase, ICalc2Contract { ICalculator _view; public Calc2V1ViewToV2ContractAddInSideAdapter(ICalculator calc) { _view = calc; } public string GetAvailableOperations() { return "+, -, *, /" ; } public double Operate(string operation, double a, double b) { switch (operation) { case "+": return _view.Add(a, b); case "-": return _view.Subtract(a, b); case "*": return _view.Multiply(a, b); case "/": return _view.Divide(a, b); default: throw new InvalidOperationException("This add-in does not support: " + operation); } } } }
Erstellen des hostseitigen Adapters
Dieser hostseitige Adapter besteht aus einem Vertrag-zu-Ansicht-Adapter. Ein Vertrag-zu-Ansicht-Adapter ist für die Unterstützung beider Versionen des Add-Ins ausreichend, da jeder Add-In-seitige Adapter von seiner jeweiligen Ansicht zu Version 2 des Vertrags konvertiert.
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 CalculatorV2-Projektmappe ein neues Projekt mit dem Namen Calc2HostInSideAdapter hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Calc2HostSideAdapter-Projekt Verweise auf die folgenden Assemblys hinzu:
System.AddIn.dll
System.AddIn.Contract.dll
Fügen Sie den folgenden Projekten Projektverweise hinzu:
Calc2Contract
Calc2HVA
Wählen Sie die einzelnen Projektverweise aus, und legen Sie unter Eigenschaften die Option Lokale Kopie auf False fest, damit die Assemblys, auf die verwiesen wird, nicht in den lokalen Buildordner kopiert werden. 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 Calc2HVA.CalcHVAs und Calc2Contract.CalculatorContracts, sofern der Standardnamespace für Visual Basic-Projekte nicht deaktiviert wurde.)
Wenden Sie das HostAdapterAttribute-Attribut auf die CalculatorContractToViewHostSideAdapter-Klasse an, um es als hostseitigen Adapter zu identifizieren.
Lassen Sie die CalculatorContractToViewHostSideAdapter-Klasse von der abstrakten Basisklasse erben, die die Host-Ansicht des Add-Ins darstellt: CalcHVAs.Calculator (Calc2HVA.CalcHVAs.Calculator in Visual Basic). Beachten Sie den Unterschied zu Version 1, in der die Hostansicht des Add-Ins eine Schnittstelle ist.
Fügen Sie einen öffentlichen Konstruktor hinzu, der den Pipelinevertragstyp ICalc2Contract 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.
Wenn Sie die Member von Calculator überschreiben möchten, rufen Sie einfach die entsprechenden Member der ICalc2Contract-Instanz auf, die dem Konstruktor übergeben wird, und geben die Ergebnisse zurück. Dadurch wird der Vertrag (ICalc2Contract) an die Ansicht (Calculator) angepasst.
Im folgenden Code wird das vervollständigte hostseitige Adaptersegment dargestellt.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Pipeline Imports Calc2HVA.CalcHVAs Imports Calc2Contract.CalculatorContracts Namespace CalculatorContractsHostAdapers <HostAdapter()> _ Public Class CalculatorContractToViewHostAdapter Inherits Calculator Private _contract As ICalc2Contract Private _handle As ContractHandle Public Sub New(ByVal contract As ICalc2Contract) _contract = contract _handle = New ContractHandle(contract) End Sub Public Overrides ReadOnly Property Operations() As String Get Return _contract.GetAvailableOperations() End Get End Property Public Overrides Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double Return _contract.Operate(operation, a, b) End Function End Class End Namespace
using System.AddIn.Pipeline; using CalcHVAs; using CalculatorContracts; namespace CalcHostSideAdapters { [HostAdapter] public class CalculatorContractToViewHostAdapter : Calculator { private CalculatorContracts.ICalc2Contract _contract; private System.AddIn.Pipeline.ContractHandle _handle; public CalculatorContractToViewHostAdapter(ICalc2Contract contract) { _contract = contract; _handle = new System.AddIn.Pipeline.ContractHandle(contract); } public override string Operations { get { return _contract.GetAvailableOperations(); } } public override double Operate(string operation, double a, double b) { return _contract.Operate(operation, a, b); } } }
Erstellen des Hosts
Eine Hostanwendung interagiert durch die Hostansicht 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:
Neuerstellen des Caches der Pipeline- und Add-In-Informationen.
Suchen von Add-Ins vom Typ Calculator unter dem angegebenen Pipelinestammverzeichnis.
Auffordern des Benutzers zur Angabe, welches Add-In verwendet werden soll. In diesem Beispiel sehen Sie zwei verfügbare Add-Ins.
Aktivieren des ausgewählten Add-Ins mit einer angegebenen Sicherheitsvertrauensebene in einer neuen Anwendungsdomäne.
Ausführen der 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 CalculatorV2-Projektmappe ein neues Projekt mit dem Namen MathHost2 hinzu. Verwenden Sie die Konsolenanwendungsvorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem MathHost2-Projekt einen Verweis auf die System.AddIn.dll-Assembly hinzu.
Fügen Sie dem Calc2HVA-Projekt einen Projektverweis hinzu. Wählen Sie den Projektverweis aus, und legen Sie unter Eigenschaften die Option Lokale Kopie auf False fest, damit die Assembly, auf die verwiesen wird, nicht in den lokalen Buildordner kopiert wird. 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 MathHost2 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 Calc2HVA.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.
Erstellen Sie mit dem folgenden Code die Hostanwendung.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Collections.ObjectModel Imports System.Text Imports System.AddIn.Hosting Imports Calc2HVA.CalcHVAs Namespace Mathhost Module MathHost2 Sub Main() ' Assume that the current directory is the application folder, ' and that it contains the pipeline folder structure. Dim pipeRoot As String = Environment.CurrentDirectory & "\Pipeline" ' Rebuild the cache of pipline and add-in information. AddInStore.Rebuild(pipeRoot) ' Find add-ins of type Calculator under the specified pipeline root directory. Dim tokens As Collection(Of AddInToken) = AddInStore.FindAddIns(GetType(Calculator), pipeRoot) ' Determine which add-in to use. Dim calcToken As AddInToken = ChooseCalculator(tokens) ' Activate the selected AddInToken in a new ' application domain with a specified security trust level. Dim calculator As Calculator = calcToken.Activate(Of Calculator)(AddInSecurityLevel.Internet) ' Run the calculator. RunCalculator(calculator) End Sub Private Function ChooseCalculator(ByVal tokens As Collection(Of AddInToken)) As AddInToken If tokens.Count = 0 Then Console.WriteLine("No calculators are available") Return Nothing End If Console.WriteLine("Available Calculators: ") ' Show the token properties for each token ' in the AddInToken collection (tokens), ' preceded by the add-in number in [] brackets. Dim tokNumber As Integer = 1 For Each tok As AddInToken In tokens Console.WriteLine(vbTab & "[{0}]: {1} - {2}" & _ vbLf & vbTab & "{3}" & _ vbLf & vbTab & "{4}" & _ vbLf & vbTab & "{5} - {6}", _ tokNumber.ToString, tok.Name, _ tok.AddInFullName, tok.AssemblyName, _ tok.Description, tok.Version, tok.Publisher) tokNumber = tokNumber + 1 Next Console.WriteLine("Which calculator do you want to use?") Dim line As String = Console.ReadLine() Dim selection As Integer If Int32.TryParse(line, selection) Then If selection <= tokens.Count Then Return tokens(selection - 1) End If End If Console.WriteLine("Invalid selection: {0}. Please choose again.", line) Return ChooseCalculator(tokens) End Function Private Sub RunCalculator(ByVal calc As Calculator) If calc Is Nothing Then 'No calculators were found, read a line and exit Console.ReadLine() End If Console.WriteLine("Available operations: " & calc.Operations) Console.WriteLine("Request a calculation , such as: 2 + 2") Console.WriteLine("Type ""exit"" to exit") Dim line As String = Console.ReadLine() Do While Not line.Equals("exit") ' Parser Try Dim c As Parser = New Parser(line) Console.WriteLine(calc.Operate(c.action, c.A, c.B)) Catch Console.WriteLine("Invalid command: {0}. Commands must be formated: [number] [operation] [number]", line) Console.WriteLine("Available operations: " & calc.Operations) End Try line = Console.ReadLine() Loop End Sub End Module Friend Class Parser Public partA As Double Public partB As Double Public action As String Friend Sub New(ByVal line As String) MyBase.New() Dim parts() As String = line.Split(" ") partA = Double.Parse(parts(0)) action = parts(1) partB = Double.Parse(parts(2)) End Sub Public ReadOnly Property A() As Double Get Return partA End Get End Property Public ReadOnly Property B() As Double Get Return partB End Get End Property Public ReadOnly Property CalcAction() As String Get Return action End Get End Property End Class End Namespace
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using System.AddIn.Hosting; using CalcHVAs; namespace MathHost { class Program { static void Main() { // Assume that the current directory is the application folder, // and that it contains the pipeline folder structure. String addInRoot = Environment.CurrentDirectory + "\\Pipeline"; //Check to see if new add-ins have been installed. AddInStore.Rebuild(addInRoot); //Search for Calculator add-ins. Collection<AddInToken> tokens = AddInStore.FindAddIns(typeof(Calculator), addInRoot); //Ask the user which add-in they would like to use. AddInToken calcToken = ChooseCalculator(tokens); //Activate the selected AddInToken in a new //application domain with the Internet trust level. Calculator calculator = calcToken.Activate<Calculator>(AddInSecurityLevel.Internet); //Run the add-in. RunCalculator(calculator); } private static AddInToken ChooseCalculator(Collection<AddInToken> tokens) { if (tokens.Count == 0) { Console.WriteLine("No calculators are available"); return null; } Console.WriteLine("Available Calculators: "); // Show the token properties for each token // in the AddInToken collection (tokens), // preceded by the add-in number in [] brackets. int tokNumber = 1; foreach (AddInToken tok in tokens) { Console.WriteLine(String.Format("\t[{0}]: {1} - {2}\n\t{3}\n\t\t {4}\n\t\t {5} - {6}", tokNumber.ToString(), tok.Name, tok.AddInFullName, tok.AssemblyName, tok.Description, tok.Version, tok.Publisher)); tokNumber++; } Console.WriteLine("Which calculator do you want to use?"); String line = Console.ReadLine(); int selection; if (Int32.TryParse(line, out selection)) { if (selection <= tokens.Count) { return tokens[selection - 1]; } } Console.WriteLine("Invalid selection: {0}. Please choose again.", line); return ChooseCalculator(tokens); } private static void RunCalculator(Calculator calc) { if (calc == null) { //No calculators were found, read a line and exit. Console.ReadLine(); } Console.WriteLine("Available operations: " + calc.Operations); Console.WriteLine("Type \"exit\" to exit"); String line = Console.ReadLine(); while (!line.Equals("exit")) { // The Parser class parses the user's input. try { Parser c = new Parser(line); Console.WriteLine(calc.Operate(c.Action, c.A, c.B)); } catch { Console.WriteLine("Invalid command: {0}. Commands must be formated: [number] [operation] [number]", line); Console.WriteLine("Available operations: " + calc.Operations); } line = Console.ReadLine(); } } } internal class Parser { internal Parser(String line) { String[] parts = line.Trim().Split(' '); a = Double.Parse(parts[0]); action = parts[1]; b = Double.Parse(parts[2]); } double a; public double A { get { return a; } } double b; public double B { get { return b; } } String action; public String Action { get { return action; } } } }
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.
Erstellen des Add-Ins
Ein Add-In implementiert die von der Add-In-Ansicht angegebenen Methoden. In diesem Add-In gibt die Operations-Methode eine Zeichenfolge mit einer Auflistung der mathematischen Operationen zurück, die das Add-In unterstützt. Die Operate-Methode stellt den Code zum Berechnen des Ergebnisses auf der Grundlage der Auswahl einer Operation und von zwei Zahlen durch den Host bereit.
So erstellen Sie das Add-In
Fügen Sie der Projektmappe CalculatorV2 ein neues Projekt mit dem Namen AddInCalcV2 hinzu. Verwenden Sie die Klassenbibliothek-Vorlage als Grundlage.
Fügen Sie im Projektmappen-Explorer dem Projekt AddInCalcV2 Verweise auf die folgenden Assemblys hinzu:
System.AddIn.dll
System.AddIn.Contract.dll
Fügen Sie dem Calc2AddInView-Projekt einen Projektverweis hinzu. Wählen Sie den Projektverweis aus, und legen Sie unter Eigenschaften die Option Lokale Kopie auf False fest, damit die Assembly, auf die verwiesen wird, nicht in den lokalen Buildordner kopiert wird. In Visual Basic kann unter Projekteigenschaften auf der Registerkarte Verweise die Option Lokale Kopie auf False festgelegt werden.
Benennen Sie die Klassendatei in SampleV2AddIn um.
Fügen Sie in der Klassendatei Namespaceverweise auf System.AddIn und auf System.AddIn.Pipeline hinzu. System.AddIn.Pipeline ist nur deshalb erforderlich, da der Code ein Beispiel für das QualificationDataAttribute-Attribut enthält.
Fügen Sie in der Klassendatei einen Namespaceverweis für Version 2 des Add-In-Ansichtssegments hinzu: CalcAddInViews (Calc2AddInView.CalcAddInViews in Visual Basic).
Wenden Sie das AddInAttribute-Attribut auf die SampleV2AddIn-Klasse an, um die Klasse als Add-In zu kennzeichnen.
Wenden Sie das QualificationDataAttribute-Attribut auf die SampleV2AddIn-Klasse an, und geben Sie Informationen an, die der Host vom AddInToken abrufen kann. In diesem Fall enthalten die Informationen die Empfehlung, das Add-In in seine eigene Anwendungsdomäne zu laden. Siehe Gewusst wie: Verwenden von Qualifizierungsdaten.
Lassen Sie die SampleV2AddIn-Klasse von der abstrakten Basisklasse Calculator2 erben, die die Add-In-Ansicht darstellt.
Überschreiben Sie die Member von Calculator2, und geben Sie die Ergebnisse der entsprechenden Berechnungen zurück.
Mit dem folgenden Code wird das vollständige Add-In dargestellt.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn Imports System.AddIn.Pipeline Imports Calc2AddInView.CalcAddInViews Namespace CalculatorAddIns ' This pipeline segment has ' two attributes: ' 1 - An AddInAttribute to identify ' this segment as an add-in. ' ' 2 - A QualificationDataAttribute to ' indicate that the add-in should ' be loaded into a new application domain. <AddIn("Calculator Add-in", Version:="2.0.0.0")> _ <QualificationData("Isolation", "NewAppDomain")> _ Public Class SampleV2AddIn Inherits Calculator2 Public Overrides ReadOnly Property Operations() As String Get Return "+, -, *, /, **" End Get End Property Public Overrides Function Operate(ByVal operation As String, _ ByVal a As Double, ByVal b As Double) As Double Select Case operation Case "+" Return a + b Case "-" Return a - b Case "*" Return a * b Case "/" Return a / b Case "**" Return Math.Pow(a, b) Case Else Throw New InvalidOperationException("This add-in does not support: " & operation) End Select End Function End Class End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn; using System.AddIn.Pipeline; using CalcAddInViews; namespace CalcAddIns { // This pipeline segment has // two attributes: // 1 - An AddInAttribute to identify // this segment as an add-in. // // 2 - A QualificationDataAttribute to // indicate that the add-in should // be loaded into a new application domain. [AddIn("Calculator Add-in",Version="2.0.0.0")] [QualificationData("Isolation", "NewAppDomain")] public class SampleV2AddIn : Calculator2 { public override string Operations { get { return "+, -, *, /, **"; } } public override double Operate(string operation, double a, double b) { switch (operation) { case "+": return a + b; case "-": return a - b; case "*": return a * b; case "/": return a / b; case "**": return Math.Pow(a, b); default: throw new InvalidOperationException("This add-in does not support: " + operation); } } } }
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
AddInCalcV2
MyApp\Pipeline\AddIns\CalcV2
Calc2AddInSideAdapter
MyApp\Pipeline\AddInSideAdapters
Calc2V1toV2AddInSideAdapter
MyApp\Pipeline\AddInSideAdapters
Calc1AddInView
MyApp\Pipeline\AddInViews
Calc2AddInView
MyApp\Pipeline\AddInViews
Calc2Contract
MyApp\Pipeline\Contracts
MathHost2
MyApp
Calc2HostSideAdapter
MyApp\Pipeline\HostSideAdapters
Calc2HVA
MyApp
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.
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 AddInCalcV2-Projekt für den Calc2AddInView-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 den Add-Ins interagieren.
So führen Sie die Hostanwendung aus
Stellen Sie sicher, dass beide Versionen des Add-Ins bereitgestellt wurden.
Navigieren Sie an der Eingabeaufforderung zum Anwendungsverzeichnis, und führen Sie die Hostanwendung aus. In diesem Beispiel ist die Hostanwendung MathHost2.exe.
Der Host sucht alle verfügbaren Add-Ins von seinem Typ und fordert Sie auf, ein Add-In auszuwählen. Geben Sie 1 oder 2 ein.
Geben Sie eine Formel für den Rechner ein, z. B. 2 + 2.
Geben Sie exit ein, und drücken Sie die EINGABETASTE, um die Anwendung zu schließen.
Wiederholen Sie die Schritte 2 bis 5, um das andere Add-In auszuführen.
Siehe auch
Aufgaben
Exemplarische Vorgehensweise: Erstellen von erweiterbaren Anwendungen
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. |