Procedura dettagliata: creazione di un'applicazione estendibile
Aggiornamento: Luglio 2008
In questa procedura dettagliata viene descritto come creare una pipeline per un componente aggiuntivo che esegue semplici funzioni di calcolo. Non viene illustrato uno scenario realistico, bensì la funzionalità di base di una pipeline e il modo in cui un componente aggiuntivo può fornire servizi per un host.
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.
Creazione dell'adattatore sul lato host.
Creazione dell'host.
Creazione del componente aggiuntivo.
Distribuzione della pipeline.
Esecuzione dell'applicazione host.
Questa pipeline passa solo tipi serializzabili, Double e String, tra l'host e il componente aggiuntivo. Per un esempio che illustra come passare insiemi di tipi di dati complessi, vedere Procedura dettagliata: passaggio di insiemi tra host e componenti aggiuntivi.
Il contratto per questa pipeline definisce un modello a oggetti di quattro operazioni aritmetiche: addizione, sottrazione, moltiplicazione e divisione. L'host fornisce al componente aggiuntivo un'equazione da calcolare, ad esempio 2 + 2, e il componente aggiuntivo restituisce il risultato all'host.
Nella versione 2 del componente aggiuntivo della calcolatrice vengono fornite maggiori possibilità di calcolo e viene dimostrato il controllo delle versioni. Queste operazioni vengono descritte in Procedura dettagliata: attivazione della compatibilità con le versioni precedenti in base alle modifiche dell'host.
Nota: |
---|
Per ulteriori esempi di codice e anteprime di tecnologie di clienti riguardanti strumenti di creazione di pipeline per componenti aggiuntivi, vedere Managed Extensibility and Add-In Framework on CodePlex (informazioni in lingua inglese). |
Prerequisiti
Per completare questa procedura dettagliata, sono necessari i seguenti elementi:
- Visual Studio.
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 Calc1Contract, basandolo sul modello Libreria di classi.
Denominare la soluzione CalculatorV1.
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 ulteriori informazioni sulla struttura della pipeline, vedere Requisiti di sviluppo delle pipeline.
Per creare la struttura di directory della pipeline
Creare una cartella di applicazione in un qualsiasi percorso del computer.
In tale cartella creare la struttura seguente:
Pipeline AddIns CalcV1 CalcV2 AddInSideAdapters AddInViews Contracts HostSideAdapters
Non è necessario inserire la struttura di cartelle della pipeline nella cartella dell'applicazione; in questa procedura viene fatto solo per motivi di praticità. Nel passaggio appropriato della procedura dettagliata viene illustrato come modificare il codice se la struttura di cartelle della pipeline è in un percorso diverso. Per informazioni sui requisiti di directory della pipeline, vedere Requisiti di sviluppo delle pipeline.
Nota: La cartella CalcV2 non viene utilizzata in questa procedura dettagliata; è un segnaposto per Procedura dettagliata: attivazione della compatibilità con le versioni precedenti in base alle modifiche dell'host.
Creazione del contratto e delle visualizzazioni
Il segmento del contratto per questa pipeline definisce l'interfaccia ICalc1Contract, che a sua volta definisce quattro metodi: add, subtract, multiply e divide.
Per creare il contratto
Nella soluzione di Visual Studio denominata CalculatorV1 aprire il progetto Calc1Contract.
In Esplora soluzioni aggiungere riferimenti ai seguenti assembly per il progetto Calc1Contract.
System.AddIn.Contract.dll
System.AddIn.dll
In Esplora soluzioni, escludere la classe predefinita aggiunta ai nuovi progetti Libreria di classi.
In Esplora soluzioni aggiungere un nuovo elemento al progetto utilizzando il modello Interfaccia. Nella finestra di dialogo Aggiungi nuovo elemento, denominare l'interfaccia ICalc1Contract.
Nel file di interfaccia aggiungere i riferimenti agli spazi dei nomi System.AddIn.Contract e System.AddIn.Pipeline.
Utilizzare il codice seguente per completare questo segmento del contratto. Questa interfaccia deve disporre dell'attributo AddInContractAttribute.
Imports System.AddIn.Contract Imports System.AddIn.Pipeline Namespace CalculatorContracts ' The AddInContractAttribute identifes this pipeline segment as a ' contract. <AddInContract()> _ Public Interface ICalc1Contract Inherits IContract Function Add(ByVal a As Double, ByVal b As Double) As Double Function Subtract(ByVal a As Double, ByVal b As Double) As Double Function Multiply(ByVal a As Double, ByVal b As Double) As Double Function Divide(ByVal a As Double, ByVal b As Double) As Double End Interface End Namespace
using System.AddIn.Contract; using System.AddIn.Pipeline; namespace CalculatorContracts { // The AddInContractAttribute identifes this pipeline segment as a // contract. [AddInContract] public interface ICalc1Contract : IContract { double Add(double a, double b); double Subtract(double a, double b); double Multiply(double a, double b); double Divide(double a, double b); } }
Facoltativamente, compilare la soluzione di Visual Studio. La soluzione non può essere eseguita sino alla procedura finale, ma la compilazione al termine di ogni procedura assicura che ogni progetto sia corretto.
Poiché la visualizzazione del componente aggiuntivo e la visualizzazione host del componente aggiuntivo condividono in genere lo stesso codice, particolarmente nella prima versione del componente aggiuntivo, è 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
Aggiungere un nuovo progetto denominato Calc1AddInView alla soluzione CalculatorV1, basandolo sul modello Libreria di classi.
In Esplora soluzioni aggiungere un riferimento a System.AddIn.dll per il progetto Calc1AddInView.
In Esplora soluzioni, escludere la classe predefinita aggiunta ai nuovi progetti Libreria di classi e aggiungere un nuovo elemento al progetto utilizzando il modello Interfaccia. Nella finestra di dialogo Aggiungi nuovo elemento, denominare l'interfaccia ICalculator.
Nel file di interfaccia aggiungere un riferimento allo spazio dei nomi System.AddIn.Pipeline.
Utilizzare il codice seguente per completare questa visualizzazione del componente aggiuntivo. Questa interfaccia deve disporre dell'attributo AddInBaseAttribute.
Imports System.AddIn.Pipeline Namespace CalcAddInViews ' The AddInBaseAttribute identifes this interface as the basis for the ' add-in view pipeline segment. <AddInBaseAttribute()> _ Public Interface ICalculator Function Add(ByVal a As Double, ByVal b As Double) As Double Function Subtract(ByVal a As Double, ByVal b As Double) As Double Function Multiply(ByVal a As Double, ByVal b As Double) As Double Function Divide(ByVal a As Double, ByVal b As Double) As Double End Interface End Namespace
using System.AddIn.Pipeline; namespace CalcAddInViews { // The AddInBaseAttribute identifes this interface as the basis for // the add-in view pipeline segment. [AddInBase()] public interface ICalculator { double Add(double a, double b); double Subtract(double a, double b); double Multiply(double a, double b); double Divide(double a, double b); } }
Facoltativamente, compilare la soluzione di Visual Studio.
Per creare la visualizzazione host del componente aggiuntivo
Aggiungere un nuovo progetto denominato Calc1HVA alla soluzione CalculatorV1, basandolo sul modello Libreria di classi.
In Esplora soluzioni, escludere la classe predefinita aggiunta ai nuovi progetti Libreria di classi e aggiungere un nuovo elemento al progetto utilizzando il modello Interfaccia. Nella finestra di dialogo Aggiungi nuovo elemento, denominare l'interfaccia ICalculator.
Nel file di interfaccia utilizzare il codice seguente per completare questa visualizzazione host del componente aggiuntivo.
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); } }
Facoltativamente, compilare la soluzione di Visual Studio.
Creazione dell'adattatore sul lato componente aggiuntivo
Questo adattatore sul lato componente aggiuntivo è costituito da un adattatore visualizzazione-contratto. Questo segmento della pipeline converte i tipi dalla visualizzazione del componente aggiuntivo nel contratto.
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 sul lato componente aggiuntivo di questa pipeline.
Per creare l'adattatore sul lato componente aggiuntivo
Aggiungere un nuovo progetto denominato Calc1AddInSideAdapter alla soluzione CalculatorV1, basandolo sul modello Libreria di classi.
In Esplora soluzioni aggiungere riferimenti ai seguenti assembly per il progetto Calc1AddInSideAdapter.
System.AddIn.dll
System.AddIn.Contract.dll
Aggiungere riferimenti ai progetti per i segmenti della pipeline adiacenti:
Calc1AddInView
Calc1Contract
Selezionare ogni riferimento al progetto e in Proprietà 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 CalculatorViewToContractAddInSideAdapter 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: CalcAddInViews e CalculatorContracts. In Visual Basic, questi riferimenti agli spazi dei nomi sono Calc1AddInView.CalcAddInViews e Calc1Contract.CalculatorContracts, a meno che siano stati disattivati gli spazi dei nomi predefiniti nei progetti di Visual Basic.
Applicare l'attributo AddInAdapterAttribute alla classe CalculatorViewToContractAddInSideAdapter, per identificarla come adattatore sul lato componente aggiuntivo.
Impostare la classe CalculatorViewToContractAddInSideAdapter in modo che erediti ContractBase, che fornisce un'implementazione predefinita dell'interfaccia IContract e implementa l'interfaccia del contratto per la pipeline, ICalc1Contract.
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 ICalc1Contract, chiamare semplicemente i membri corrispondenti dell'istanza ICalculator passata al costruttore e restituire i risultati. In questo modo la visualizzazione (ICalculator) viene adattata al contratto (ICalc1Contract).
Nel codice seguente viene illustrato l'adattatore sul lato componente aggiuntivo completato.
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); } } }
Facoltativamente, compilare la soluzione di Visual Studio.
Creazione dell'adattatore sul lato host
Questo adattatore sul lato host è costituito da un adattatore contratto-visualizzazione. Questo segmento adatta il contratto alla visualizzazione host del componente aggiuntivo.
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 Calc1HostSideAdapter alla soluzione CalculatorV1, basandolo sul modello Libreria di classi.
In Esplora soluzioni aggiungere riferimenti ai seguenti assembly per il progetto Calc1HostSideAdapter.
System.AddIn.dll
System.AddIn.Contract.dll
Aggiungere riferimenti ai progetti per i segmenti adiacenti:
Calc1Contract
Calc1HVA
Selezionare ogni riferimento al progetto e in Proprietà 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 Calc1HVA.CalcHVAs e Calc1Contract.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 segmento dell'adattatore sul lato host.
Impostare la classe CalculatorContractToViewHostSideAdapter in modo che implementi l'interfaccia che rappresenta la visualizzazione host del componente aggiuntivo: Calc1HVAs.ICalculator (Calc1HVA.CalcHVAs.ICalculator in Visual Basic).
Aggiungere un costruttore pubblico che accetta il tipo di contratto della pipeline, ICalc1Contract. 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.
Nota 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.
Per implementare i membri di ICalculator, chiamare semplicemente i membri corrispondenti dell'istanza ICalc1Contract passata al costruttore e restituire i risultati. In questo modo il contratto (ICalc1Contract) viene adattato alla visualizzazione (ICalculator).
Nel codice seguente viene illustrato l'adattatore sul lato host completato.
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); } } }
Facoltativamente, compilare la soluzione di Visual Studio.
Creazione dell'host
Un'applicazione host interagisce con il componente aggiuntivo tramite la visualizzazione host del componente aggiuntivo. Utilizza i metodi di individuazione e attivazione del componente aggiuntivo forniti dalle classi AddInStore e AddInToken per effettuare le operazioni seguenti:
Aggiornare la cache di informazioni sulla pipeline e sui componenti aggiuntivi.
Trovare i componenti aggiuntivi del tipo di visualizzazione host, ICalculator, nella directory radice della pipeline specificata.
Richiedere all'utente di specificare il componente aggiuntivo da utilizzare.
Attivare il componente aggiuntivo selezionato in un nuovo dominio applicazione con un livello di attendibilità della sicurezza specificato.
Eseguire il metodo personalizzato RunCalculator che chiama i metodi del componente aggiuntivo specificati dalla visualizzazione host del componente aggiuntivo.
Per creare l'host
Aggiungere un nuovo progetto denominato Calc1Host alla soluzione CalculatorV1, basandolo sul modello Applicazione console.
In Esplora soluzioni aggiungere un riferimento all'assembly System.AddIn.dll per il progetto Calc1Host.
Aggiungere un riferimento di progetto al progetto Calc1HVA. Selezionare il riferimento al progetto e in Proprietà 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) MathHost1.
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 è Calc1HVA.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.
Nel file di classe o di modulo, utilizzare il metodo AddInStore.Update per aggiornare la cache. Utilizzare il metodo AddInStore.FindAddIn per ottenere un insieme di token e il metodo AddInToken.Activate per attivare un componente aggiuntivo.
Nel codice seguente viene illustrata l'applicazione host completata.
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; } } } }
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.
Nel codice viene utilizzato un metodo ChooseCalculator per elencare i token e richiedere all'utente di scegliere un componente aggiuntivo. Il metodo RunCalculator richiede all'utente semplici espressioni matematiche, analizza le espressioni utilizzando la classe Parser e visualizza i risultati restituiti dal componente aggiuntivo.
Facoltativamente, compilare la soluzione di Visual Studio.
Creazione del componente aggiuntivo
Un componente aggiuntivo implementa i metodi specificati dalla visualizzazione del componente aggiuntivo. Questo componente aggiuntivo implementa le operazioni Add, Subtract, Multiply e Divide e restituisce i risultati all'host.
Per creare il componente aggiuntivo
Aggiungere un nuovo progetto denominato AddInCalcV1 alla soluzione CalculatorV1, basandolo sul modello Libreria di classi.
In Esplora soluzioni aggiungere un riferimento all'assembly System.AddIn.dll per il progetto.
Aggiungere un riferimento al progetto Calc1AddInView. Selezionare il riferimento al progetto e in Proprietà impostare Copia localmente su False. In Visual Basic, utilizzare la scheda Riferimenti di Proprietà progetti per impostare Copia localmente su False per il riferimento al progetto.
Rinominare la classe AddInCalcV1.
Nel file di classe, aggiungere un riferimento allo spazio dei nomi System.AddIn e il segmento della visualizzazione del componente aggiuntivo: CalcAddInViews (Calc1AddInView.CalcAddInViews in Visual Basic).
Applicare l'attributo AddInAttribute alla classe AddInCalcV1, per identificarla come componente aggiuntivo.
Impostare la classe AddInCalcV1 in modo che implementi l'interfaccia che rappresenta la visualizzazione del componente aggiuntivo: CalcAddInViews.ICalculator (Calc1AddInView.CalcAddInViews.ICalculator in Visual Basic).
Implementare i membri di ICalculator restituendo i risultati dei calcoli appropriati.
Nel codice seguente viene illustrato il componente aggiuntivo completato.
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; } } }
Facoltativamente, compilare la soluzione di Visual Studio.
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:
Progetto
Percorso
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
Nota: Se si è deciso di inserire la struttura di cartelle della pipeline in un percorso diverso dalla cartella dell'applicazione, è necessario modificare di conseguenza i percorsi mostrati nella tabella. Per informazioni sui requisiti di directory della pipeline, vedere Requisiti di sviluppo delle pipeline.
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 Calc1AddInView nel progetto AddInCalcV1, 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 il componente aggiuntivo.
Per eseguire l'applicazione host
Al prompt dei comandi, passare alla directory dell'applicazione ed eseguire l'applicazione host, Calc1Host.exe.
L'host trova tutti i componenti aggiuntivi disponibili del tipo specificato e chiede all'utente di selezionarne uno. Immettere 1 per il solo componente aggiuntivo disponibile.
Immettere un'equazione per la calcolatrice, ad esempio 2 + 2. Tra i numeri e l'operatore devono essere presenti spazi.
Digitare exit e premere INVIO per chiudere l'applicazione.
Vedere anche
Attività
Procedura dettagliata: passaggio di insiemi tra host e componenti aggiuntivi
Concetti
Requisiti di sviluppo delle pipeline
Contratti, visualizzazioni e adattatori
Cronologia delle modifiche
Date |
History |
Motivo |
---|---|---|
Luglio 2008 |
Errori corretti nel testo. Aggiunta una nota sul mantenimento di un riferimento al contratto. |
Commenti e suggerimenti dei clienti. |