Procedura dettagliata: abilitazione della compatibilità con le versioni precedenti in base alle modifiche dell'host
In questa procedura dettagliata viene descritta la versione 2 della pipeline descritta in Procedura dettagliata: creazione di un'applicazione estendibile. Nella versione 2 sono incluse ulteriori funzionalità di calcolo fornite da una stringa con valori delimitati da virgole di operazioni aritmetiche supportate per l'host. L'host può quindi scegliere un'operazione e inviare un'equazione al componente aggiuntivo per l'esecuzione del calcolo.
La pipeline dispone di un nuovo host e un nuovo contratto. Per consentire alla versione 1 del componente aggiuntivo di interagire con un host e un contratto nuovi, nella pipeline è inclusa la visualizzazione del componente aggiuntivo utilizzata per la versione 1 e un adattatore sul lato componente aggiuntivo che converte i dati dalla visualizzazione del componente aggiuntivo precedente nel nuovo contratto. Nella figura seguente è illustrata la modalità di funzionamento di entrambi i componenti aggiuntivi con lo stesso host.
Nuovo host, componenti aggiuntivi precedenti
Questa pipeline è descritta anche in Scenari con pipeline di componenti aggiuntivi.
In questa procedura dettagliata vengono descritte le attività seguenti:
Creazione di una soluzione di Visual Studio.
Creazione della struttura di directory della pipeline.
Creazione del contratto e delle visualizzazioni.
Creazione dell'adattatore sul lato componente aggiuntivo che include adattatori per la nuova versione del componente aggiuntivo e per il componente aggiuntivo della versione 1.
Creazione dell'adattatore sul lato host.
Creazione dell'host.
Creazione del componente aggiuntivo.
Distribuzione della pipeline.
Esecuzione dell'applicazione host.
Nella procedura dettagliata viene inoltre illustrato l'utilizzo delle classi di base astratte per definire visualizzazioni e viene mostrato che tali visualizzazioni sono compatibili con le visualizzazioni definite dalle interfacce. L'utilizzo delle interfacce è consigliato.
Nota |
---|
Parte del codice mostrato in questa procedura dettagliata contiene riferimenti a spazi dei nomi estranei.I passaggi della procedura dettagliata riflettono accuratamente i riferimenti richiesti in Visual Studio. |
Per ulteriori esempi di codice e anteprime di tecnologie di clienti riguardanti strumenti di compilazione di pipeline per componenti aggiuntivi, vedere Managed Extensibility and Add-In Framework on CodePlex (informazioni in lingua inglese).
Prerequisiti
Per completare la procedura dettagliata, è necessario disporre dei componenti seguenti:
Visual Studio.
La versione 1 della pipeline descritta in Procedura dettagliata: creazione di un'applicazione estendibile. Poiché nella versione 2 vengono utilizzati i segmenti di pipeline sviluppati nella versione 1, è necessario sviluppare e distribuire la pipeline versione 1 prima di eseguire i passaggi descritti in questo argomento.
Creazione di una soluzione di Visual Studio
Per contenere i progetti dei segmenti di pipeline, utilizzare una soluzione di Visual Studio.
Per creare la soluzione della pipeline
In Visual Studio creare un nuovo progetto denominato Calc2Contract, basandolo sul modello Libreria di classi.
Denominare la soluzione CalculatorV2.
Creazione della struttura di directory della pipeline
Il modello del componente aggiuntivo richiede che gli assembly dei segmenti di pipeline siano inseriti in una struttura di directory specificata.
Per creare la struttura di directory della pipeline
Se non lo si è ancora fatto, aggiungere la cartella CalcV2 alla struttura di cartelle della pipeline creata in Procedura dettagliata: creazione di un'applicazione estendibile. La cartella CalcV2 conterrà la nuova versione del componente aggiuntivo.
Pipeline AddIns CalcV1 CalcV2 AddInSideAdapters AddInViews Contracts HostSideAdapters
Non è necessario inserire la struttura di cartelle della pipeline nella cartella dell'applicazione; in queste procedure dettagliate viene fatto solo per motivi di praticità. Se nella prima procedura dettagliata si è inserita la struttura di cartelle della pipeline in un percorso diverso, seguire lo stesso modello anche per questa. Per informazioni sui requisiti di directory della pipeline, vedere Requisiti di sviluppo delle pipeline.
Creazione del contratto e delle visualizzazioni
Il segmento del contratto per questa pipeline definisce l'interfaccia ICalc2Contract che dispone dei due metodi seguenti:
Metodo GetAvailableOperations.
Questo metodo restituisce una stringa delle operazioni matematiche supportate dal componente aggiuntivo per l'host. Nella versione 2 sono supportate cinque operazioni e questo metodo restituisce la stringa "+,-,*,/,**", dove "**" rappresenta l'operazione Pow.
Nelle visualizzazioni del componente aggiuntivo e host questo metodo è denominato Operations anziché GetAvailableOperations.
È possibile esporre i metodi nel contratto come proprietà delle visualizzazioni convertendo la chiamata al metodo in una proprietà dell'adattatore.
Metodo Operate.
L'host chiama questo metodo per inviare un'equazione al componente aggiuntivo per l'esecuzione del calcolo e la restituzione del risultato.
Per creare il contratto
Nella soluzione di Visual Studio denominata CalculatorV2 aprire il progetto Calc2Contract.
In Esplora soluzioni aggiungere riferimenti ai seguenti assembly per il progetto Calc2Contract.
System.AddIn.Contract.dll
System.AddIn.dll
In Esplora soluzioni, escludere la classe predefinita aggiunta ai nuovi progetti Libreria di classi.
Aggiungere un nuovo elemento al progetto, utilizzando il modello Interfaccia. Nella finestra di dialogo Aggiungi nuovo elemento, denominare l'interfaccia ICalc2Contract.
Nel file di interfaccia aggiungere i riferimenti agli spazi dei nomi System.AddIn.Contract e System.AddIn.Pipeline.
Utilizzare il codice seguente per completare il segmento del contratto. Questa interfaccia deve disporre dell'attributo AddInContractAttribute.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Contract Imports System.AddIn.Pipeline Namespace CalculatorContracts <AddInContract()> _ Public Interface ICalc2Contract Inherits IContract Function GetAvailableOperations() As String Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double End Interface End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn.Contract; using System.AddIn.Pipeline; namespace CalculatorContracts { [AddInContract] public interface ICalc2Contract : IContract { string GetAvailableOperations(); double Operate(String operation, double a, double b); } }
Poiché la visualizzazione del componente aggiuntivo e la visualizzazione host condividono lo stesso codice, è possibile crearle con facilità contemporaneamente. Tali visualizzazioni differiscono per un solo fattore: la visualizzazione del componente aggiuntivo richiede l'attributo AddInBaseAttribute, mentre la visualizzazione host del componente aggiuntivo non richiede attributi.
Per creare la visualizzazione del componente aggiuntivo per la versione 2
Aggiungere un nuovo progetto denominato Calc2AddInView alla soluzione CalculatorV2, basandolo sul modello Libreria di classi.
In Esplora soluzioni aggiungere un riferimento a System.AddIn.dll per il progetto Calc2AddInView.
Rinominare la classe Calculator2.
Nel file di classe aggiungere un riferimento allo spazio dei nomi System.AddIn.Pipeline.
Impostare Calculator2 come classe abstract (classe MustInherit in Visual Basic).
Utilizzare il codice seguente per questa visualizzazione del componente aggiuntivo. Questa classe deve disporre dell'attributo AddInBaseAttribute.
Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports System.AddIn.Pipeline Namespace CalcAddInViews <AddInBase()> _ Public MustInherit Class Calculator2 Public MustOverride ReadOnly Property Operations() As String Public MustOverride Function Operate(ByVal operation As String, ByVal a As Double, ByVal b As Double) As Double End Class End Namespace
using System; using System.Collections.Generic; using System.Text; using System.AddIn.Pipeline; namespace CalcAddInViews { [AddInBase] public abstract class Calculator2 { public abstract string Operations { get; } public abstract double Operate(string operation, double a, double b); } }
Per creare la visualizzazione host del componente aggiuntivo
Aggiungere un nuovo progetto denominato Calc2HVA alla soluzione CalculatorV2, basandolo sul modello Libreria di classi.
Rinominare la classe Calculator.
Impostare Calculator come classe abstract (classe MustInherit in Visual Basic).
Nel file di classe utilizzare il codice seguente per creare la visualizzazione host del componente aggiuntivo.
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); } }
Per illustrare l'utilizzo del componente aggiuntivo della versione 1 con il nuovo host, la soluzione deve includere la visualizzazione del componente aggiuntivo creata per la versione 1 del componente aggiuntivo relativo alla calcolatrice.
Per aggiungere il progetto della visualizzazione del componente aggiuntivo per la versione 1
In Esplora soluzioni fare clic con il pulsante destro del mouse sulla soluzione CalculatorV2.
Fare clic su Aggiungi, quindi su Progetto esistente.
Individuare le cartelle che contengono la soluzione CalculatorV1, quindi selezionare il file di progetto per il progetto Calc1AddInView.
Creazione dell'adattatore sul lato componente aggiuntivo
Questo adattatore sul lato componente aggiuntivo è costituito da due adattatori visualizzazione-contratto: uno per adattare la visualizzazione del componente aggiuntivo della versione 2 al contratto della versione 2 e uno per adattare la visualizzazione del componente aggiuntivo della versione 1 al contratto della versione 2.
In questa pipeline il componente aggiuntivo fornisce un servizio all'host e il flusso dei tipi passa dal componente aggiuntivo all'host. Poiché non vengono passati tipi dall'host al componente aggiuntivo, non è necessario includere un adattatore contratto-visualizzazione.
Per creare l'adattatore sul lato componente aggiuntivo
Aggiungere un nuovo progetto denominato Calc2AddInSideAdapter alla soluzione CalculatorV2, basandolo sul modello Libreria di classi.
In Esplora soluzioni aggiungere riferimenti ai seguenti assembly per il progetto Calc2AddInSideAdapter.
System.AddIn.dll
System.AddIn.Contract.dll
Aggiungere riferimenti di progetto ai progetti seguenti:
Calc2AddInView
Calc2Contract
Selezionare ogni riferimento a progetto e, per impedire che gli assembly a cui si fa riferimento vengano copiati nella cartella di compilazione locale, accedere a Proprietà e impostare Copia localmente su False. Gli assembly saranno situati nella directory della pipeline, come descritto nella procedura "Distribuzione della pipeline" più avanti in questa procedura dettagliata. In Visual Basic, utilizzare la scheda Riferimenti di Proprietà progetti per impostare Copia localmente su False per i due riferimenti al progetto.
Rinominare la classe predefinita CalculatorViewToContractAddInSideAdapter del progetto.
Nel file di classe aggiungere un riferimento allo spazio dei nomi System.AddIn.Pipeline.
Nel file di classe aggiungere i riferimenti agli spazi dei nomi per i segmenti adiacenti: CalcAddInViews e CalculatorContracts. In Visual Basic, questi riferimenti agli spazi dei nomi sono Calc2AddInView.CalcAddInViews e Calc2Contract.CalculatorContracts, a meno che siano stati disattivati gli spazi dei nomi predefiniti nei progetti di Visual Basic.
Utilizzare il codice seguente per questo adattatore sul lato componente aggiuntivo. Il modello di implementazione è simile all'adattatore sul lato componente aggiuntivo per la versione 1, anche se l'interfaccia del contratto è molto diversa.
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); } } }
Per consentire alla versione 1 del componente aggiuntivo di comunicare con il nuovo host, la pipeline del componente aggiuntivo della versione 1 richiede un adattatore sul lato componente aggiuntivo per la conversione dei dati dalla visualizzazione del componente aggiuntivo precedente al nuovo contratto.
Per creare l'adattatore dalla versione 1 alla versione 2 sul lato componente aggiuntivo
Aggiungere un nuovo progetto denominato Calc2V1toV2AddInSideAdapter alla soluzione CalculatorV2, basandolo sul modello Libreria di classi.
In Esplora soluzioni aggiungere riferimenti ai seguenti assembly per il progetto Calc2V1toV2AddInSideAdapter.
System.AddIn.dll
System.AddIn.Contract.dll
Aggiungere riferimenti di progetto ai progetti seguenti:
Calc1AddInView
Calc2Contract
Selezionare ogni riferimento a progetto e, per impedire che gli assembly a cui si fa riferimento vengano copiati nella cartella di compilazione locale, accedere a Proprietà e impostare Copia localmente su False. In Visual Basic, utilizzare la scheda Riferimenti di Proprietà progetti per impostare Copia localmente su False per i due riferimenti al progetto.
Rinominare la classe predefinita Calc2V1ViewToV2ContractAddInSideAdapter del progetto.
Nel file di classe aggiungere un riferimento allo spazio dei nomi System.AddIn.Pipeline.
Nel file di classe aggiungere i riferimenti agli spazi dei nomi per i segmenti adiacenti: CalcAddInViews e CalculatorContracts. In Visual Basic, questi riferimenti agli spazi dei nomi sono Calc1AddInView.CalcAddInViews e Calc2Contract.CalculatorContracts, a meno che siano stati disattivati gli spazi dei nomi predefiniti nei progetti di Visual Basic. Notare che lo spazio dei nomi della visualizzazione proviene dalla versione 1 e il contratto dalla versione 2.
Applicare l'attributo AddInAdapterAttribute alla classe Calc2V1ViewToV2ContractAddInSideAdapter, per identificarla come adattatore sul lato componente aggiuntivo.
Impostare la classe Calc2V1ViewToV2ContractAddInSideAdapter in modo che erediti ContractBase, che fornisce un'implementazione predefinita dell'interfaccia IContract e implementa l'interfaccia del contratto della versione 2 per la pipeline, ICalc2Contract.
Aggiungere un costruttore pubblico che accetta ICalculator, lo memorizza nella cache in un campo privato e chiama il costruttore della classe di base.
Per implementare i membri di ICalc2Contract, chiamare i membri appropriati dell'istanza ICalculator passata al costruttore e restituire i risultati. A causa delle differenze tra le interfacce dei contratti delle versioni 1 e 2, è necessario disporre di un'istruzione switch (istruzioneSelect Case in Visual Basic) per adattare la visualizzazione (ICalculator) al contratto (ICalc2Contract).
Nel codice seguente viene illustrato l'adattatore sul lato componente aggiuntivo completato.
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); } } } }
Creazione dell'adattatore sul lato host
Questo adattatore sul lato host è costituito da un adattatore contratto-visualizzazione. Un adattatore contratto-visualizzazione è sufficiente per supportare entrambe le versioni del componente aggiuntivo, perché ogni adattatore sul lato componente aggiuntivo esegue la conversione dalla rispettiva visualizzazione al contratto della versione 2.
In questa pipeline il componente aggiuntivo fornisce un servizio all'host e il flusso dei tipi passa dal componente aggiuntivo all'host. Poiché non vengono passati tipi dall'host al componente aggiuntivo, non è necessario includere un adattatore visualizzazione-contratto.
Per implementare gestione della durata, utilizzare un oggetto ContractHandle per connettere un token di durata al contratto. È necessario mantenere un riferimento a questo handle affinché la gestione della durata funzioni. Dopo l'applicazione del token non è necessaria un'ulteriore fase di programmazione perché il sistema dei componenti aggiuntivi può eliminare gli oggetti quando non vengono più utilizzati, rendendoli disponibili per l'operazione di Garbage Collection. Per ulteriori informazioni, vedere Gestione della durata.
Per creare l'adattatore sul lato host
Aggiungere un nuovo progetto denominato Calc2HostSideAdapter alla soluzione CalculatorV2, basandolo sul modello Libreria di classi.
In Esplora soluzioni aggiungere riferimenti ai seguenti assembly per il progetto Calc2HostSideAdapter.
System.AddIn.dll
System.AddIn.Contract.dll
Aggiungere riferimenti di progetto ai progetti seguenti:
Calc2Contract
Calc2HVA
Selezionare ogni riferimento a progetto e, per impedire che gli assembly a cui si fa riferimento vengano copiati nella cartella di compilazione locale, accedere a Proprietà e impostare Copia localmente su False. In Visual Basic, utilizzare la scheda Riferimenti di Proprietà progetti per impostare Copia localmente su False per i due riferimenti al progetto.
Rinominare la classe predefinita CalculatorContractToViewHostSideAdapter del progetto.
Nel file di classe aggiungere i riferimenti allo spazio dei nomi System.AddIn.Pipeline.
Nel file di classe aggiungere i riferimenti agli spazi dei nomi per i segmenti adiacenti: CalcHVAs e CalculatorContracts. In Visual Basic, questi riferimenti agli spazi dei nomi sono Calc2HVA.CalcHVAs e Calc2Contract.CalculatorContracts, a meno che siano stati disattivati gli spazi dei nomi predefiniti nei progetti di Visual Basic.
Applicare l'attributo HostAdapterAttribute alla classe CalculatorContractToViewHostSideAdapter, per identificarla come adattatore sul lato host.
Impostare la classe CalculatorContractToViewHostSideAdapter in modo che erediti la classe di base astratta che rappresenta la visualizzazione host del componente aggiuntivo: CalcHVAs.Calculator (Calc2HVA.CalcHVAs.Calculator in Visual Basic). Notare la differenza dalla versione 1, in cui la visualizzazione host del componente aggiuntivo è un'interfaccia.
Aggiungere un costruttore pubblico che accetta il tipo di contratto della pipeline, ICalc2Contract. Il costruttore deve memorizzare nella cache il riferimento al contratto. Deve inoltre creare e memorizzare nella cache un nuovo oggetto ContractHandle per il contratto, per gestire la durata del componente aggiuntivo.
Importante L'oggetto ContractHandle è di importanza fondamentale nella gestione della durata.Se non si riesce a mantenere un riferimento all'oggetto ContractHandle, quest'ultimo verrà recuperato dalla Garbage Collection e la pipeline verrà interrotta in un momento non previsto dal programma.Ciò può comportare errori difficili da diagnosticare, ad esempio AppDomainUnloadedException.L'arresto è una fase normale del ciclo di vita di una pipeline. Pertanto, non esiste alcun modo in cui il codice di gestione della durata sia in grado di rilevare questa condizione come un errore.
Quando si esegue l'override dei membri di Calculator, chiamare semplicemente i membri corrispondenti dell'istanza ICalc2Contract passata al costruttore e restituire i risultati. In questo modo il contratto (ICalc2Contract) viene adattato alla visualizzazione (Calculator).
Nel codice seguente viene illustrato il segmento dell'adattatore sul lato host completato.
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); } } }
Creazione dell'host
Un'applicazione host interagisce con il componente aggiuntivo tramite la visualizzazione host. Utilizza i metodi di individuazione e attivazione del componente aggiuntivo forniti dalle classi AddInStore e AddInToken per eseguire le operazioni seguenti:
Ricompilare la cache di informazioni sulla pipeline e sui componenti aggiuntivi.
Cercare i componenti aggiuntivi di tipo Calculator nella directory radice della pipeline specificata.
Richiedere all'utente di specificare il componente aggiuntivo da utilizzare. In questo esempio sono disponibili due componenti aggiuntivi.
Attivare il componente aggiuntivo selezionato in un nuovo dominio applicazione con un livello di attendibilità della sicurezza specificato.
Eseguire il metodo RunCalculator che chiama i metodi del componente aggiuntivo resi disponibili dalla visualizzazione host del componente aggiuntivo.
Per creare l'host
Aggiungere un nuovo progetto denominato MathHost2 alla soluzione CalculatorV2, basandolo sul modello Applicazione console.
In Esplora soluzioni aggiungere un riferimento all'assembly System.AddIn.dll per il progetto MathHost2.
Aggiungere un riferimento di progetto al progetto Calc2HVA. Selezionare il riferimento a progetto e, per impedire che l'assembly a cui si fa riferimento venga copiato nella cartella di compilazione locale, accedere a Proprietà e impostare Copia localmente su False. In Visual Basic, utilizzare la scheda Riferimenti di Proprietà progetti per impostare Copia localmente su False.
Rinominare il file di classe (il modulo in Visual Basic) MathHost2.
In Visual Basic, utilizzare la scheda Applicazione della finestra di dialogo Proprietà progetti per impostare Oggetto di avvio su Sub Main.
Nel file di classe o di modulo aggiungere un riferimento allo spazio dei nomi System.AddIn.Hosting.
Nel file di classe o di modulo, aggiungere un riferimento allo spazio dei nomi per la visualizzazione host del componente aggiuntivo: CalcHVAs. In Visual Basic, questo riferimento allo spazio dei nomi è Calc2HVA.CalcHVAs, a meno che siano stati disattivati gli spazi dei nomi predefiniti nei progetti di Visual Basic.
In Esplora soluzioni selezionare la soluzione, quindi scegliere Proprietà dal menu Progetto. Nella finestra di dialogo Pagine delle proprietà di Soluzione impostare Progetto di avvio singolo in modo che venga utilizzato come progetto di questa applicazione host.
Utilizzare il codice seguente per creare l'applicazione host.
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; } } } }
Nota In questo codice si presuppone che la struttura di cartelle della pipeline si trovi nella cartella dell'applicazione.Se si trova in percorso diverso, modificare la riga di codice che imposta la variabile addInRoot, in modo che la variabile contenga il percorso della struttura di directory della pipeline.
Creazione del componente aggiuntivo
Un componente aggiuntivo implementa i metodi specificati dalla visualizzazione del componente aggiuntivo. In questo componente aggiuntivo il metodo Operations restituisce una stringa con l'elenco delle operazioni matematiche supportate dal componente aggiuntivo. Il metodo Operate fornisce il codice per calcolare il risultato in base alla selezione dell'host di un'operazione e due numeri.
Per creare il componente aggiuntivo
Aggiungere un nuovo progetto denominato AddInCalcV2 alla soluzione CalculatorV2, basandolo sul modello Libreria di classi.
In Esplora soluzioni aggiungere riferimenti ai seguenti assembly per il progetto AddInCalcV2:
System.AddIn.dll
System.AddIn.Contract.dll
Aggiungere un riferimento di progetto al progetto Calc2AddInView. Selezionare il riferimento a progetto e, per impedire che l'assembly a cui si fa riferimento venga copiato nella cartella di compilazione locale, accedere a Proprietà e impostare Copia localmente su False. In Visual Basic, utilizzare la scheda Riferimenti di Proprietà progetti per impostare Copia localmente su False.
Rinominare il file di classe SampleV2AddIn.
Nel file di classe aggiungere riferimenti agli spazi dei nomi a System.AddIn e System.AddIn.Pipeline. System.AddIn.Pipeline è necessario solo perché il codice include un esempio dell'attributo QualificationDataAttribute.
Nel file di classe, aggiungere un riferimento allo spazio dei nomi per il segmento della visualizzazione del componente aggiuntivo della versione 2: CalcAddInViews (Calc2AddInView.CalcAddInViews in Visual Basic).
Applicare l'attributo AddInAttribute alla classe SampleV2AddIn, per identificarla come componente aggiuntivo.
Applicare l'attributo QualificationDataAttribute alla classe SampleV2AddIn e specificare le informazioni che l'host può recuperare da AddInToken. In questo caso, le informazioni suggeriscono che il componente aggiuntivo deve essere caricato nel proprio dominio applicazione. Vedere Procedura: utilizzare dati di qualificazione.
Impostare la classe SampleV2AddIn in modo che erediti la classe di base astratta che rappresenta la visualizzazione del componente aggiuntivo: Calculator2.
Eseguire l'override dei membri di Calculator2 e restituire i risultati dei calcoli appropriati.
Nel codice seguente viene illustrato il componente aggiuntivo completato.
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); } } } }
Distribuzione della pipeline
A questo punto è possibile procedere alla compilazione e distribuzione dei segmenti del componente aggiuntivo alla struttura di directory della pipeline richiesta.
Per distribuire i segmenti alla pipeline
Per ogni progetto nella soluzione, utilizzare la scheda Compilazione di Proprietà progetto (la scheda Compilazione anche in Visual Basic) per impostare il valore di Percorso output (Percorso dell'output di compilazione in Visual Basic). Se, ad esempio, si è denominata la cartella dell'applicazione MyApp, i progetti saranno compilati nelle cartelle seguenti:
Project
Percorso
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
Nota Se si è inserita la struttura di cartelle della pipeline in un percorso diverso dalla cartella dell'applicazione, è necessario modificare di conseguenza i percorsi mostrati nella tabella.
Compilare la soluzione di Visual Studio.
Controllare nelle directory dell'applicazione e della pipeline che gli assembly siano stati copiati nelle directory corrette e che non siano state installate copie supplementari degli assembly nelle cartelle errate.
Nota Se Copia localmente non è stato impostato su False per il riferimento al progetto Calc2AddInView nel progetto AddInCalcV2, problemi di contesto del caricatore impediranno l'individuazione del componente aggiuntivo.
Per ulteriori informazioni sulla distribuzione alla pipeline, vedere Requisiti di sviluppo delle pipeline.
Esecuzione dell'applicazione host
A questo punto è possibile eseguire l'host e interagire con i componenti aggiuntivi.
Per eseguire l'applicazione host
Verificare che vengano distribuite entrambe le versioni del componente aggiuntivo.
Al prompt dei comandi passare alla directory dell'applicazione ed eseguire l'applicazione host. In questo esempio l'applicazione host è MathHost2.exe.
L'host cerca tutti i componenti aggiuntivi disponibili del tipo specificato e chiede all'utente di selezionarne uno. Immettere 1 o 2.
Immettere un'equazione per la calcolatrice, ad esempio 2 + 2.
Digitare exit e premere INVIO per chiudere l'applicazione.
Ripetere i passaggi 2-5 per eseguire l'altro componente aggiuntivo.
Vedere anche
Attività
Procedura dettagliata: creazione di un'applicazione estendibile
Procedura dettagliata: passaggio di insiemi tra host e componenti aggiuntivi
Concetti
Requisiti di sviluppo delle pipeline