Compartilhar via


Demonstra Passo a passo: Coleções de passagem entre hosts e suplementos

Esta explicação passo a passo descreve como criar um pipeline que passa uma coleção de objetos personalizados entre um suplemento e um host.Como os tipos na coleção não são serializáveis, additional classes que definem o tipo exibição-para-contrato e adaptadores de contrato para exibição devem ser adicionados aos segmentos de adaptador para que o fluxo de tipos pode cruzar o limite de isolamento.

Nesse cenário, o suplemento atualiza uma coleção de objetos de catálogo para o host.Cada objeto de catálogo contém métodos que obtém e conjunto o título do livro, editora, preço e outros dados.

sistema autônomo uma demonstração, o host cria uma coleção de catálogo; o suplemento diminui o preço de todos sistema autônomo livros de informática em 20 por cento e remove todos sistema autônomo livros de terror da coleção.O suplemento cria um novo objeto de catálogo para o catálogo mais vendido e passa para o host sistema autônomo um único objeto.

Essa explicação passo a passo ilustra as seguintes tarefas:

  • Criando uma solução do Visual Studio.

  • Criando a estrutura de diretório do pipeline.

  • Criando contratos e exibições para objetos que devem ser passados de e para trás entre o limite de isolamento.

  • Criando os adaptadores de adição no lado e do host necessários para passar objetos entre o limite de isolamento.

  • Criando o host.

  • Criando o add-no.

  • Implantando o pipeline.

  • Executar o aplicativo host.

Observação:

Parte do código mostrado nesta explicação passo a passo contém referências a namespace irrelevantes.As etapas do passo-a-passo refletem com precisão as referências necessárias no Visual Studio.

Você pode encontrar código de exemplo adicionais e prévias de tecnologia do cliente de ferramentas para a criação de tubulações suplemento, com o Site de extensibilidade e suplemento estrutura gerenciado no CodePlex.

Pré-requisitos

Para completar este passo a passo, são necessários os seguintes componentes:

Criando uma solução do Visual Studio

Use uma solução no Visual Studio para conter projetos dos segmentos de pipeline.

Para criar a solução de pipeline

  1. No Visual Studio, criar um novo projeto chamado LibraryContracts.Basear o biblioteca de classes modelo.

  2. Nomeie a solução BooksPipeline.

Criando a estrutura de diretório de pipeline

O modelo de suplemento requer que os assemblies de segmento pipeline seja colocado em uma estrutura de diretórios especificada.

Para criar a estrutura de diretório de pipeline

  • Crie a seguinte estrutura de pastas no computador.Você pode localizá-lo em qualquer lugar, inclusive nas pastas de sua solução do Visual Studio.

    Pipeline
      AddIns
        BooksAddIn
      AddInSideAdapters
      AddInViews
      Contracts
      HostSideAdapters
    

    Todos sistema autônomo nomes de pasta devem ser especificados exatamente sistema autônomo mostrado aqui, exceto para o nome da pasta raiz e sistema autônomo nomes das pastas individuais de suplemento.Este exemplo usa Pipeline sistema autônomo o nome da pasta raiz e BooksAddIn sistema autônomo o nome da pasta suplemento.

    Observação:

    Para sua conveniência, a explicação passo a passo locais o aplicativo host a pipeline r pasta OOT.Na etapa de apropriado, a explicação passo a passo explica como alterar o código se o aplicativo está em um local diferente.

    Para obter mais informações sobre a estrutura de pasta do pipeline, consulte Requisitos de desenvolvimento de pipeline.

Criação do contrato e exibições

O segmento de contrato para esse pipeline define duas interfaces:

  • A interface IBookInfoContract.

    Essa interface contém métodos, sistema autônomo Author, que contêm informações sobre um livro.

  • A interface ILibraryManagerContract.

    Essa interface contém o ProcessBooks método que o suplemento usa para processar uma coleção de livros. Cada livro representa um IBookInfoContract contrato. A interface também contém o GetBestSeller método que o suplemento usa para fornecer um objeto de catálogo, que representa o livro mais vendido, para o host.

Para criar o contrato

  1. Na solução Visual Studio chamada BooksPipeline, em aberto the LibraryContractsprojeto .

  2. No Visual Basic, em aberto Propriedades for the LibraryContracts projeto e usar o Aplicativo guia para excluir o valor padrão fornecido para Namespace raiz.Por padrão, Namespace raiz é definida como o nome do projeto.

  3. In O gerenciador de soluções, adicionar referências aos seguintes assemblies para o projeto:

    Sytem.AddIn.contrato.dll

    sistema.AddIn.dll

  4. No arquivo classe, adicione referências para o System.AddIn.Contract e System.AddIn.Pipeline espaços para nome.

  5. No arquivo de classe, substitua a declaração da classe padrão com duas interfaces:

    • The ILibraryManagerContract interface é usada para ativar o suplemento, portanto, ele deve ter o AddInContractAttribute atributo.

    • The IBookInfoContract interface representa um objeto que é transmitido entre o host e o suplemento, para que ele não requer o atributo.

    As duas interfaces devem herdar a IContract interface.

  6. Use o código a seguir para adicionar o IBookInfoContract e ILibraryManagerContract interfaces.

    Imports Microsoft.VisualBasic
    Imports System
    Imports System.Collections.Generic
    Imports System.Text
    Imports System.AddIn.Pipeline
    Imports System.AddIn.Contract
    Namespace Library
    <AddInContract> _
    Public Interface ILibraryManagerContract
    Inherits IContract
        ' Pass a collection of books,
        ' of type IBookInfoContract
        ' to the add-in for processing.
        Sub ProcessBooks(ByVal books As IListContract(Of IBookInfoContract))
    
        ' Get a IBookInfoContract object
        ' from the add-in of the
        ' the best selling book.
        Function GetBestSeller() As IBookInfoContract
    
        ' This method has has arbitrary
        ' uses and shows how you can
        ' mix serializable and custom types.
        Function Data(ByVal txt As String) As String
    End Interface
    
    ' Contains infomration about a book.
    Public Interface IBookInfoContract
    Inherits IContract
        Function ID() As String
        Function Author() As String
        Function Title() As String
        Function Genre() As String
        Function Price() As String
        Function Publish_Date() As String
        Function Description() As String
    End Interface
    End Namespace
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.AddIn.Pipeline;
    using System.AddIn.Contract;
    namespace Library
    {
        [AddInContract]
        public interface ILibraryManagerContract : IContract
        {
            // Pass a collection of books,
            // of type IBookInfoContract
            // to the add-in for processing.
            void ProcessBooks(IListContract<IBookInfoContract> books);
    
            // Get a IBookInfoContract object
            // from the add-in of the
            // the best selling book.
            IBookInfoContract GetBestSeller();
    
            // This method has has arbitrary
            // uses and shows how you can
            // mix serializable and custom types.
            string Data(string txt);
        }
    
        // Contains infomration about a book.
        public interface IBookInfoContract : IContract
        {
            string ID();
            string Author();
            string Title();
            string Genre();
            string Price();
            string Publish_Date();
            string Description();
        }
    }
    

Como o modo de exibição de suplemento e o modo de exibição de host tem o mesmo código, você pode criar com com facilidade os modos de exibição ao mesmo time.Diferem em apenas um fator: o exibição de suplemento que é usado para ativar esse segmento do pipeline requer o AddInBaseAttribute atributo; o host de modo de exibição não requer quaisquer atributos.

exibição de suplemento para esse pipeline contém duas classes abstratas.The BookInfo classe fornece o modo de exibição para o IBookInfoContract interface e o LibraryManager classe fornece o modo de exibição para o ILibraryManagerContract interface.

Para criar exibição de suplemento

  1. Adicionar um novo projeto denominado AddInViews to the BooksPipeline solução.Basear o biblioteca de classes modelo.

  2. No Visual Basic, abra o Propriedades para o projeto e utilize o Aplicativo guia para excluir o valor padrão fornecido para Namespace raiz.

  3. In O gerenciador de soluções, adicione uma referência ao sistema.AddIn.dll à AddInViewsprojeto .

  4. Renomear de classe do projeto padrão LibraryManagere tornar a classe abstract (MustInherit no Visual Basic).

  5. No arquivo de classe, adicione uma referência à System.AddIn.Pipeline espaço para nome.

  6. The LibraryManager classe é usada para ativar o pipeline, para que você deve aplicar o AddInBaseAttribute atributo.

  7. Use o código a seguir para concluir o abstract LibraryManager classe.

    Imports Microsoft.VisualBasic
    Imports System
    Imports System.Collections.Generic
    Imports System.AddIn.Pipeline
    Namespace LibraryContractsBase
    ' The AddInBaseAttribute
    ' identifes this pipeline
    ' segment as an add-in view.
    <AddInBase> _
    Public MustInherit Class LibraryManager
        Public MustOverride Sub ProcessBooks(ByVal books As IList(Of BookInfo))
        Public MustOverride Function GetBestSeller() As BookInfo
    
        Public MustOverride Function Data(ByVal txt As String) As String
    End Class
    End Namespace
    
    using System;
    using System.Collections.Generic;
    using System.AddIn.Pipeline;
    namespace LibraryContractsBase
    {
    // The AddInBaseAttribute
    // identifes this pipeline
    // segment as an add-in view.
    [AddInBase]
        public abstract class LibraryManager
        {
            public abstract void ProcessBooks(IList<BookInfo> books);
            public abstract BookInfo GetBestSeller();
    
            public abstract string Data(string txt);
        }
    }
    
  8. Adicionar um abstract (classeMustInherit classe no Visual Basic) para o projeto e denomine-a BookInfo.The BookInfo classe representa um objeto que é transmitido entre o host e o suplemento.Esta classe não é usada para ativar o pipeline, para que ele não requer quaisquer atributos.

  9. Use o código a seguir para concluir o abstract BookInfo classe.

    Imports Microsoft.VisualBasic
    Imports System
    Namespace LibraryContractsBase
    
    Public MustInherit Class BookInfo
    
        Public MustOverride Function ID() As String
        Public MustOverride Function Author() As String
        Public MustOverride Function Title() As String
        Public MustOverride Function Genre() As String
        Public MustOverride Function Price() As String
        Public MustOverride Function Publish_Date() As String
        Public MustOverride Function Description() As String
    End Class
    End Namespace
    
    using System;
    namespace LibraryContractsBase {
    
        public abstract class BookInfo {
    
            public abstract string ID();
            public abstract string Author();
            public abstract string Title();
            public abstract string Genre();
            public abstract string Price();
            public abstract string Publish_Date();
            public abstract string Description();
        }
    }
    

Para criar a exibição de host

  1. Adicionar um novo projeto denominado HostViews to the BooksPipeline solução.Basear o biblioteca de classes modelo.

  2. No Visual Basic, abra o Propriedades para o projeto e utilize o Aplicativo guia para excluir o valor padrão fornecido para Namespace raiz.

  3. Renomear de classe do projeto padrão LibraryManagere tornar a classe abstract (MustInherit no Visual Basic).

  4. Use o código a seguir para concluir o abstract LibraryManager classe.

    Imports Microsoft.VisualBasic
    Imports System.Collections.Generic
    Namespace LibraryContractsHAV
    
    Public MustInherit Class LibraryManager
    
    Public MustOverride Sub ProcessBooks(ByVal books As System.Collections.Generic.IList(Of BookInfo))
    Public MustOverride Function GetBestSeller() As BookInfo
    
    Public MustOverride Function Data(ByVal txt As String) As String
    End Class
    End Namespace
    
    using System.Collections.Generic;
    namespace LibraryContractsHAV {
    
    public abstract class LibraryManager
    {
    
        public abstract void ProcessBooks(System.Collections.Generic.IList<BookInfo> books);
        public abstract BookInfo GetBestSeller();
    
        public abstract string Data(string txt);
    }
    }
    
  5. Adicionar um abstract (classeMustInherit classe no Visual Basic) para o projeto e denomine-a BookInfo.

  6. Use o código a seguir para concluir o abstract BookInfo classe.

    Imports Microsoft.VisualBasic
    Imports System
    Namespace LibraryContractsHAV
        Public MustInherit Class BookInfo
    
            Public MustOverride Function ID() As String
            Public MustOverride Function Author() As String
            Public MustOverride Function Title() As String
            Public MustOverride Function Genre() As String
            Public MustOverride Function Price() As String
            Public MustOverride Function Publish_Date() As String
            Public MustOverride Function Description() As String
        End Class
    End Namespace
    
    namespace LibraryContractsHAV
    {
        public abstract class BookInfo
        {
    
            public abstract string ID();
            public abstract string Author();
            public abstract string Title();
            public abstract string Genre();
            public abstract string Price();
            public abstract string Publish_Date();
            public abstract string Description();
        }
    }
    

Criando o adaptador de suplemento-side

O conjunto de adaptador no lado do suplemento deste pipeline contém quatro classes de adaptador:

  • BookInfoContractToViewAddInAdapter

    Esse adaptador é chamado quando o host passa um BookInfo objeto para o suplemento, por si mesmo ou sistema autônomo parte de uma coleção. Essa classe converte o contrato do BookInfo objeto a um modo de exibição. A classe herda o modo de exibição do suplemento e implementa os métodos abstratos do modo de exibição chamando o contrato é passado para o construtor da classe.

    O construtor para o adaptador utiliza um contrato, para que um ContractHandle objeto podem ser aplicadas no contrato de implementação do gerenciamento de tempo de vida.

    Observação importante:

    O ContractHandle é fundamental para o gerenciamento da tempo de vida. Se você não conseguir manter uma referência à ContractHandle o objeto, coleta de lixo será solicitá-lo e a tubulação será desligado quando seu programa não espera. Isso pode levar a erros que são difíceis de diagnosticar como sistema autônomo AppDomainUnloadedException. desligado é um preparar da tempo de vida de um pipeline normal, portanto, não é possível para o código de gerenciamento de tempo de vida detectar essa condição é um erro.

  • BookInfoViewToContractAddInAdapter

    Esse adaptador é chamado quando o suplemento passa um BookInfo objeto para o host. Essa classe converte exibição de suplemento do BookInfo objeto a um contrato. A classe herda a partir do contrato e implementa o contrato chamando exibição de suplemento que é passada para o construtor da classe.Esse adaptador é empacotado para o host sistema autônomo um contrato.

  • LibraryManagerViewToContractAddInAdapter

    Esse é o tipo retornado para o host de sua telefonar para ativar o suplemento.Esse tipo é chamado quando o host chama o suplemento, incluindo a telefonar que transmite uma coleção de objetos de host (IList<BookInfo>) para o suplemento. Essa classe converte o contrato ILibraryManagerContract para o modo de exibição do host LibraryManager. Esta classe herda de exibição do host e implementa o contrato chamando o modo de exibição que é passado para seu construtor.

    Como uma coleção de tipos personalizados, a BookInfo objetos, deve ser empacotado entre o limite de isolamento, usa esse adaptador de CollectionAdapters classe. Essa classe fornece métodos para converter um IList<T> coleção para um IListContract<T> coleção, que permite a coleta a ser passada entre o limite de isolamento para o Outros lado do pipeline.

  • BookInfoAddInAdapter

    The static () métodosShared métodos no Visual Basic) deste adaptador chamado pela LibraryManagerViewToContractAddInAdapter para adaptar-se um contrato ou modo de exibição ou para retornar um contrato existente ou modo de exibição de classe. Isso impede que a criação de um adaptador adicional quando um objeto faz uma viagem de ida e volta entre o host e o suplemento.

Para criar o adaptador no lado do suplemento

  1. Adicionar um novo projeto denominado AddInSideAdapters to the BooksPipeline solução.Basear o biblioteca de classes modelo.

  2. No Visual Basic, abra o Propriedades para o projeto e utilize o Aplicativo guia para excluir o valor padrão fornecido para Namespace raiz.

  3. In O gerenciador de soluções, adicionar referências aos assemblies seguintes à AddInSideAdapters projeto:

    sistema.AddIn.dll

    sistema.AddIn.contrato.dll

  4. In O gerenciador de soluções, adicione referências a projetos a seguir para o AddInSideAdapters projeto:

    AddInViews

    LibraryContracts

    A referência Propriedades, conjunto Copiar local to False essas referências para evitar que os assemblies referenciados sejam copiadas para a pasta local de compilação.sistema autônomo assemblies estará localizados na estrutura de diretório do pipeline, conforme descrito no procedimento "Implantando o pipeline", posteriormente nesta explicação passo a passo.

  5. Nomeie o arquivo de classe BookInfoContractToViewAddInAdapter.

  6. No arquivo de classe, adicione uma referência à System.AddIn.Pipeline espaço para nome.

  7. Use o código a seguir para adicionar o BookInfoContractToViewAddInAdapter classe. A classe não requer um atributo porque não é usado para ativar o pipeline.The internal (Friend no Visual Basic) GetSourceContract método é usado pela BookInfoAddInAdapter classe para evitar a criação de um adaptador adicional quando um objeto faz uma viagem de ida e volta entre o host e o suplemento.

    Imports Microsoft.VisualBasic
    Imports System
    Imports System.AddIn.Pipeline
    Namespace LibraryContractsAddInAdapters
    
    Public Class BookInfoContractToViewAddInAdapter
        Inherits LibraryContractsBase.BookInfo
        Private _contract As Library.IBookInfoContract
        Private _handle As System.AddIn.Pipeline.ContractHandle
        Public Sub New(ByVal contract As Library.IBookInfoContract)
            _contract = contract
            _handle = New ContractHandle(contract)
        End Sub
    
        Public Overrides Function ID() As String
            Return _contract.ID()
        End Function
        Public Overrides Function Author() As String
            Return _contract.Author()
        End Function
        Public Overrides Function Title() As String
            Return _contract.Title()
        End Function
        Public Overrides Function Genre() As String
            Return _contract.Genre()
        End Function
        Public Overrides Function Price() As String
            Return _contract.Price()
        End Function
        Public Overrides Function Publish_Date() As String
            Return _contract.Publish_Date()
        End Function
        Public Overrides Function Description() As String
            Return _contract.Description()
        End Function
    
        Friend Function GetSourceContract() As Library.IBookInfoContract
            Return _contract
        End Function
    End Class
    End Namespace
    
    using System;
    using System.AddIn.Pipeline;
    namespace LibraryContractsAddInAdapters 
    {
    
    public class BookInfoContractToViewAddInAdapter : LibraryContractsBase.BookInfo 
    {
        private Library.IBookInfoContract _contract;
        private System.AddIn.Pipeline.ContractHandle _handle;
        public BookInfoContractToViewAddInAdapter(Library.IBookInfoContract contract) 
        {
            _contract = contract;
            _handle = new ContractHandle(contract);
        }
    
        public override string ID()
        {
            return _contract.ID();
        }
        public override string Author()
        {
            return _contract.Author();
        }
        public override string Title()
        {
            return _contract.Title();
        }
        public override string Genre()
        {
            return _contract.Genre();
        }
        public override string Price()
        {
            return _contract.Price();
        }
        public override string Publish_Date()
        {
            return _contract.Publish_Date();
        }
        public override string Description()
        {
            return _contract.Description();
        }
    
        internal Library.IBookInfoContract GetSourceContract() {
            return _contract;
        }
    }
    }
    
  8. Use o código a seguir para adicionar o BookInfoViewToContractAddInAdapter classe para o AddInSideAdaptersprojeto .A classe não requer um atributo porque não é usado para ativar o pipeline.The internal (Friend no Visual Basic) GetSourceView método é usado pela BookInfoAddInAdapter classe para evitar a criação de um adaptador adicional quando um objeto faz uma viagem de ida e volta entre o host e o suplemento.

    Imports Microsoft.VisualBasic
    Imports System
    
    Namespace LibraryContractsAddInAdapters
    Public Class BookInfoViewToContractAddInAdapter
        Inherits System.AddIn.Pipeline.ContractBase
        Implements Library.IBookInfoContract
        Private _view As LibraryContractsBase.BookInfo
        Public Sub New(ByVal view As LibraryContractsBase.BookInfo)
            _view = view
        End Sub
        Public Overridable Function ID() As String Implements Library.IBookInfoContract.ID
            Return _view.ID()
        End Function
        Public Overridable Function Author() As String Implements Library.IBookInfoContract.Author
            Return _view.Author()
        End Function
        Public Overridable Function Title() As String Implements Library.IBookInfoContract.Title
            Return _view.Title()
        End Function
        Public Overridable Function Genre() As String Implements Library.IBookInfoContract.Genre
            Return _view.Genre()
        End Function
        Public Overridable Function Price() As String Implements Library.IBookInfoContract.Price
            Return _view.Price()
        End Function
        Public Overridable Function Publish_Date() As String Implements Library.IBookInfoContract.Publish_Date
            Return _view.Publish_Date()
        End Function
        Public Overridable Function Description() As String Implements Library.IBookInfoContract.Description
            Return _view.Description()
        End Function
    
        Friend Function GetSourceView() As LibraryContractsBase.BookInfo
            Return _view
        End Function
    End Class
    End Namespace
    
    using System;
    
    namespace LibraryContractsAddInAdapters 
    {
    public class BookInfoViewToContractAddInAdapter : System.AddIn.Pipeline.ContractBase, Library.IBookInfoContract 
    {
        private LibraryContractsBase.BookInfo _view;
        public BookInfoViewToContractAddInAdapter(LibraryContractsBase.BookInfo view) 
        {
            _view = view;
        }
        public virtual string ID()
        {
            return _view.ID();
        }
        public virtual string Author()
        {
            return _view.Author();
        }
        public virtual string Title()
        {
            return _view.Title();
        }
        public virtual string Genre()
        {
            return _view.Genre();
        }
        public virtual string Price()
        {
            return _view.Price();
        }
        public virtual string Publish_Date()
        {
            return _view.Publish_Date();
        }
        public virtual string Description()
        {
            return _view.Description();
        }
    
        internal LibraryContractsBase.BookInfo GetSourceView() {
            return _view;
        }
    }
    }
    
  9. Use o código a seguir para adicionar o LibraryManagerViewToContractAddInAdapter classe para o AddInSideAdaptersprojeto .Essa classe requer o AddInAdapterAttribute o atributo, porque é usado para ativar o pipeline.

    The ProcessBooks método mostra como transmitir uma lista de livros entre o limite de isolamento. Ele usa o CollectionAdapters.ToIList método para converter a lista. Para converter objetos na lista, ele passa delegados para os métodos de adaptador fornecidos pelo BookInfoAddInAdapter classe.

    The GetBestSeller método mostra como passar um único BookInfo objeto entre o limite de isolamento.

    Imports Microsoft.VisualBasic
    Imports System.AddIn.Pipeline
    Imports System.AddIn.Contract
    Imports System.Collections.Generic
    Namespace LibraryContractsAddInAdapters
    ' The AddInAdapterAttribute
    ' identifes this pipeline
    ' segment as an add-in-side adapter.
    <AddInAdapter> _
    Public Class LibraryManagerViewToContractAddInAdapter
        Inherits System.AddIn.Pipeline.ContractBase
        Implements Library.ILibraryManagerContract
        Private _view As LibraryContractsBase.LibraryManager
        Public Sub New(ByVal view As LibraryContractsBase.LibraryManager)
            _view = view
        End Sub
        Public Overridable Sub ProcessBooks(ByVal books As IListContract(Of Library.IBookInfoContract)) Implements Library.ILibraryManagerContract.ProcessBooks
            _view.ProcessBooks(CollectionAdapters.ToIList(Of Library.IBookInfoContract, _
            LibraryContractsBase.BookInfo)(books, _
            AddressOf LibraryContractsAddInAdapters.BookInfoAddInAdapter.ContractToViewAdapter, _
            AddressOf LibraryContractsAddInAdapters.BookInfoAddInAdapter.ViewToContractAdapter))
        End Sub
        Public Overridable Function GetBestSeller() As Library.IBookInfoContract Implements Library.ILibraryManagerContract.GetBestSeller
            Return BookInfoAddInAdapter.ViewToContractAdapter(_view.GetBestSeller())
        End Function
    
        Public Overridable Function Data(ByVal txt As String) As String Implements Library.ILibraryManagerContract.Data
            Dim rtxt As String = _view.Data(txt)
            Return rtxt
        End Function
    
        Friend Function GetSourceView() As LibraryContractsBase.LibraryManager
            Return _view
        End Function
    End Class
    End Namespace
    
    using System.IO;
    using System.AddIn.Pipeline;
    using System.AddIn.Contract;
    using System.Collections.Generic;
    namespace LibraryContractsAddInAdapters
    {
    // The AddInAdapterAttribute
    // identifes this pipeline
    // segment as an add-in-side adapter.
    [AddInAdapter]
    public class LibraryManagerViewToContractAddInAdapter :
    System.AddIn.Pipeline.ContractBase, Library.ILibraryManagerContract
    {
        private LibraryContractsBase.LibraryManager _view;
        public LibraryManagerViewToContractAddInAdapter(LibraryContractsBase.LibraryManager view)
        {
            _view = view;
        }
        public virtual void ProcessBooks(IListContract<Library.IBookInfoContract> books)
        {
            _view.ProcessBooks(CollectionAdapters.ToIList<Library.IBookInfoContract,
                LibraryContractsBase.BookInfo>(books,
                LibraryContractsAddInAdapters.BookInfoAddInAdapter.ContractToViewAdapter,
                LibraryContractsAddInAdapters.BookInfoAddInAdapter.ViewToContractAdapter));
        }
        public virtual Library.IBookInfoContract GetBestSeller()
        {
            return BookInfoAddInAdapter.ViewToContractAdapter(_view.GetBestSeller());
        }
    
        public virtual string Data(string txt)
        {
            string rtxt = _view.Data(txt);
            return rtxt;
        }
    
        internal LibraryContractsBase.LibraryManager GetSourceView()
        {
            return _view;
        }
    }
    }
    
  10. Use o código a seguir para adicionar o BookInfoAddInAdapter classe para o AddInSideAdaptersprojeto .A classe contém dois static () métodosShared métodos no Visual Basic): ContractToViewAdapter e ViewToContractAdapter.Os métodos são internal (Friend no Visual Basic) porque eles são usados somente por outras classes de adaptador. A finalidade desses métodos é evitar a criação de um adaptador extra quando um objeto faz uma viagem de ida e volta em qualquer direção entre o host e o suplemento.Esses métodos devem ser fornecidos para adaptadores que passam objetos entre o limite de isolamento.

    Imports Microsoft.VisualBasic
    Imports System
    Namespace LibraryContractsAddInAdapters
    
    Public Class BookInfoAddInAdapter
      Friend Shared Function ContractToViewAdapter(ByVal contract As Library.IBookInfoContract) As LibraryContractsBase.BookInfo
        If (Not System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(contract)) AndAlso _
            CType(contract, Object).GetType().Equals(GetType(BookInfoViewToContractAddInAdapter)) Then
            Return (CType(contract, BookInfoViewToContractAddInAdapter)).GetSourceView()
        Else
            Return New BookInfoContractToViewAddInAdapter(contract)
        End If
    
      End Function
    
    Friend Shared Function ViewToContractAdapter(ByVal view As LibraryContractsBase.BookInfo) As Library.IBookInfoContract
        If (Not System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(view)) AndAlso _
            view.GetType().Equals(GetType(BookInfoContractToViewAddInAdapter)) Then
            Return (CType(view, BookInfoContractToViewAddInAdapter)).GetSourceContract()
        Else
            Return New BookInfoViewToContractAddInAdapter(view)
        End If
    End Function
    End Class
    End Namespace
    
    using System;
    namespace LibraryContractsAddInAdapters {
    
    public class BookInfoAddInAdapter
    {
        internal static LibraryContractsBase.BookInfo ContractToViewAdapter(Library.IBookInfoContract contract)
        {
            if (!System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(contract) &&
                (contract.GetType().Equals(typeof(BookInfoViewToContractAddInAdapter))))
            {
                return ((BookInfoViewToContractAddInAdapter)(contract)).GetSourceView();
            }
            else {
                return new BookInfoContractToViewAddInAdapter(contract);
            }
    
        }
    
        internal static Library.IBookInfoContract ViewToContractAdapter(LibraryContractsBase.BookInfo view)
        {
            if (!System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(view) &&
                (view.GetType().Equals(typeof(BookInfoContractToViewAddInAdapter))))
            {
                return ((BookInfoContractToViewAddInAdapter)(view)).GetSourceContract();
            }
            else {
                return new BookInfoViewToContractAddInAdapter(view);
            }
        }
    }
    }
    

Criando o adaptador no lado do host

Este assembly do adaptador do host para esse pipeline contém quatro classes de adaptador:

  • BookInfoContractToViewHostAdapter

    Esse adaptador é chamado quando o suplemento passa um BookInfo objeto para o host, por si mesmo ou sistema autônomo parte de uma coleção. Essa classe converte o contrato do BookInfo objeto a um modo de exibição. A classe herda de exibição do host e implementa os métodos abstratos do modo de exibição chamando o contrato é passado para o construtor da classe.

    O construtor para este adaptador utiliza um contrato para seu construtor, para que um ContractHandle objeto podem ser aplicadas no contrato de implementação do gerenciamento de tempo de vida.

    Observação importante:

    O ContractHandle é fundamental para o gerenciamento da tempo de vida. Se você não conseguir manter uma referência à ContractHandle o objeto, coleta de lixo será solicitá-lo e a tubulação será desligado quando seu programa não espera. Isso pode levar a erros que são difíceis de diagnosticar como sistema autônomo AppDomainUnloadedException. desligado é um preparar da tempo de vida de um pipeline normal, portanto, não é possível para o código de gerenciamento de tempo de vida detectar essa condição é um erro.

  • BookInfoViewToContractHostAdapter

    Esse adaptador é chamado quando o host passa um BookInfo objeto para o suplemento. Essa classe converte a exibição do host do BookInfo objeto a um contrato. A classe herda a partir do contrato e implementa o contrato chamando exibição de suplemento que é passada para o construtor da classe.Esse adaptador é empacotado para o suplemento sistema autônomo um contrato.

  • LibraryManagerContractToViewHostAdapter

    Esse adaptador é chamado quando o host passa uma coleção de BookInfo objetos para o suplemento. O suplemento executa sua implementação do ProcessBooks método neste conjunto.

    Essa classe converte a exibição do host do LibraryManager objeto a um contrato. Ele herda o contrato e implementa o contrato chamando a exibição do host que é passada para o construtor da classe.

    Como uma coleção de tipos personalizados, a BookInfo objetos, deve ser empacotado entre o limite de isolamento, usa esse adaptador de CollectionAdapters classe. Essa classe fornece métodos para converter um IList<T> coleção para um IListContract<T> coleção, que permite a coleta a ser passada entre o limite de isolamento para o Outros lado do pipeline.

  • BookInfoHostAdapter

    Esse adaptador é chamado pelo LibraryManagerViewToContractHostAdapter classe para retornar qualquer contratos existentes ou modos de exibição para a adaptação em vez de criar novas ocorrências para a telefonar. Isso evita a criação de um adaptador extra quando um objeto faz uma viagem de ida e volta em qualquer direção entre o host e o suplemento.

Para criar o adaptador do host

  1. Adicionar um novo projeto denominado HostSideAdapters to the BooksPipeline solução.Basear o biblioteca de classes modelo.

  2. No Visual Basic, abra o Propriedades para o projeto e utilize o Aplicativo guia para excluir o valor padrão fornecido para Namespace raiz.

  3. In O gerenciador de soluções, adicionar referências aos assemblies seguintes à HostSideAdapters projeto:

    sistema.AddIn.dll

    sistema.AddIn.contrato.dll

  4. In O gerenciador de soluções, adicione referências a projetos a seguir para o HostSideAdapters projeto:

    HostViews

    LibraryContracts

    A referência Propriedades, conjunto Copiar local to False essas referências para evitar que os assemblies referenciados sejam copiadas para a pasta local de compilação.

  5. No arquivo de classe, adicione uma referência à System.AddIn.Pipeline espaço para nome.

  6. Use o código a seguir para adicionar o BookInfoContractToViewHostAdapter classe. A classe não requer um atributo porque não é usado para ativar o pipeline.The internal (Friend no Visual Basic) GetSourceContract método é usado pela BookInfoAddInAdapter classe para evitar a criação de um adaptador extra quando um objeto faz uma viagem de ida e volta entre o host e o suplemento.

    Imports Microsoft.VisualBasic
    Imports System.AddIn.Pipeline
    Namespace LibraryContractsHostAdapters
    Public Class BookInfoContractToViewHostAdapter
        Inherits LibraryContractsHAV.BookInfo
        Private _contract As Library.IBookInfoContract
    
        Private _handle As ContractHandle
    
        Public Sub New(ByVal contract As Library.IBookInfoContract)
            _contract = contract
            _handle = New ContractHandle(contract)
        End Sub
    
        Public Overrides Function ID() As String
            Return _contract.ID()
        End Function
        Public Overrides Function Author() As String
            Return _contract.Author()
        End Function
        Public Overrides Function Title() As String
            Return _contract.Title()
        End Function
        Public Overrides Function Genre() As String
            Return _contract.Genre()
        End Function
        Public Overrides Function Price() As String
            Return _contract.Price()
        End Function
        Public Overrides Function Publish_Date() As String
            Return _contract.Publish_Date()
        End Function
        Public Overrides Function Description() As String
            Return _contract.Description()
        End Function
    
    
        Friend Function GetSourceContract() As Library.IBookInfoContract
            Return _contract
        End Function
    End Class
    End Namespace
    
    using System.AddIn.Pipeline;
    namespace LibraryContractsHostAdapters
    {
        public class BookInfoContractToViewHostAdapter : LibraryContractsHAV.BookInfo
        {
            private Library.IBookInfoContract _contract;
    
            private ContractHandle _handle;
    
            public BookInfoContractToViewHostAdapter(Library.IBookInfoContract contract)
            {
                _contract = contract;
                _handle = new ContractHandle(contract);
            }
    
            public override string ID()
            {
                return _contract.ID();
            }
            public override string Author()
            {
                return _contract.Author();
            }
            public override string Title()
            {
                return _contract.Title();
            }
            public override string Genre()
            {
                return _contract.Genre();
            }
            public override string Price()
            {
                return _contract.Price();
            }
            public override string Publish_Date()
            {
                return _contract.Publish_Date();
            }
            public override string Description()
            {
                return _contract.Description();
            }
    
    
            internal Library.IBookInfoContract GetSourceContract() {
                return _contract;
            }
        }
    }
    
  7. Use o código a seguir para adicionar o BookInfoViewToContractHostAdapter para o HostSideAdaptersprojeto .A classe não requer um atributo porque não é usado para ativar o pipeline.The internal (Friend no Visual Basic) GetSourceView método é usado pela BookInfoAddInAdapter classe para evitar a criação de um adaptador extra quando um objeto faz uma viagem de ida e volta entre o host e o suplemento.

    Imports Microsoft.VisualBasic
    Imports System.AddIn.Pipeline
    Namespace LibraryContractsHostAdapters
    Public Class BookInfoViewToContractHostAdapter
        Inherits ContractBase
        Implements Library.IBookInfoContract
        Private _view As LibraryContractsHAV.BookInfo
    
        Public Sub New(ByVal view As LibraryContractsHAV.BookInfo)
            _view = view
        End Sub
    
        Public Overridable Function ID() As String Implements Library.IBookInfoContract.ID
            Return _view.ID()
        End Function
        Public Overridable Function Author() As String Implements Library.IBookInfoContract.Author
            Return _view.Author()
        End Function
        Public Overridable Function Title() As String Implements Library.IBookInfoContract.Title
            Return _view.Title()
        End Function
        Public Overridable Function Genre() As String Implements Library.IBookInfoContract.Genre
            Return _view.Genre()
        End Function
        Public Overridable Function Price() As String Implements Library.IBookInfoContract.Price
            Return _view.Price()
        End Function
        Public Overridable Function Publish_Date() As String Implements Library.IBookInfoContract.Publish_Date
            Return _view.Publish_Date()
        End Function
        Public Overridable Function Description() As String Implements Library.IBookInfoContract.Description
            Return _view.Description()
        End Function
        Friend Function GetSourceView() As LibraryContractsHAV.BookInfo
            Return _view
        End Function
    End Class
    End Namespace
    
    using System.AddIn.Pipeline;
    namespace LibraryContractsHostAdapters
    {
    public class BookInfoViewToContractHostAdapter : ContractBase, Library.IBookInfoContract
    {
        private LibraryContractsHAV.BookInfo _view;
    
        public BookInfoViewToContractHostAdapter(LibraryContractsHAV.BookInfo view)
        {
            _view = view;
        }
    
        public virtual string ID()
        {
            return _view.ID();
        }
        public virtual string Author()
        {
            return _view.Author();
        }
        public virtual string Title()
        {
            return _view.Title();
        }
        public virtual string Genre()
        {
            return _view.Genre();
        }
        public virtual string Price()
        {
            return _view.Price();
        }
        public virtual string Publish_Date()
        {
            return _view.Publish_Date();
        }
        public virtual string Description()
        {
            return _view.Description();
        }
        internal LibraryContractsHAV.BookInfo GetSourceView()
        {
            return _view;
        }
    }
    }
    
  8. Use o código a seguir para adicionar o LibraryManagerContractToViewHostAdapter para o HostSideAdaptersprojeto .Essa classe requer o HostAdapterAttribute o atributo, porque é usado para ativar o pipeline.

    The ProcessBooks método mostra como transmitir uma lista de livros entre o limite de isolamento. Ele usa o CollectionAdapters.ToIListContract método para converter a lista. Para converter objetos na lista, ele passa delegados para os métodos de adaptador fornecidos pelo BookInfoHostAdapter classe.

    The GetBestSeller método mostra como passar um único BookInfo objeto entre o limite de isolamento.

    Imports Microsoft.VisualBasic
    Imports System.Collections.Generic
    Imports System.AddIn.Pipeline
    Namespace LibraryContractsHostAdapters
        <HostAdapterAttribute()> _
        Public Class LibraryManagerContractToViewHostAdapter
            Inherits LibraryContractsHAV.LibraryManager
    
            Private _contract As Library.ILibraryManagerContract
            Private _handle As System.AddIn.Pipeline.ContractHandle
    
            Public Sub New(ByVal contract As Library.ILibraryManagerContract)
                _contract = contract
                _handle = New System.AddIn.Pipeline.ContractHandle(contract)
            End Sub
    
            Public Overrides Sub ProcessBooks(ByVal books As IList(Of LibraryContractsHAV.BookInfo))
                _contract.ProcessBooks(CollectionAdapters.ToIListContract(Of LibraryContractsHAV.BookInfo, _
                Library.IBookInfoContract)(books, _
                AddressOf LibraryContractsHostAdapters.BookInfoHostAdapter.ViewToContractAdapter, _
                AddressOf LibraryContractsHostAdapters.BookInfoHostAdapter.ContractToViewAdapter))
            End Sub
    
            Public Overrides Function GetBestSeller() As LibraryContractsHAV.BookInfo
                Return BookInfoHostAdapter.ContractToViewAdapter(_contract.GetBestSeller())
            End Function
    
            Friend Function GetSourceContract() As Library.ILibraryManagerContract
                Return _contract
            End Function
            Public Overrides Function Data(ByVal txt As String) As String
                Dim rtxt As String = _contract.Data(txt)
                Return rtxt
            End Function
        End Class
    End Namespace
    
    using System.Collections.Generic;
    using System.AddIn.Pipeline;
    namespace LibraryContractsHostAdapters
    {
    [HostAdapterAttribute()]
    public class LibraryManagerContractToViewHostAdapter : LibraryContractsHAV.LibraryManager
    {
    
        private Library.ILibraryManagerContract _contract;
        private System.AddIn.Pipeline.ContractHandle _handle;
    
        public LibraryManagerContractToViewHostAdapter(Library.ILibraryManagerContract contract)
        {
            _contract = contract;
            _handle = new System.AddIn.Pipeline.ContractHandle(contract);
        }
    
        public override void ProcessBooks(IList<LibraryContractsHAV.BookInfo> books) {
            _contract.ProcessBooks(CollectionAdapters.ToIListContract<LibraryContractsHAV.BookInfo,
                Library.IBookInfoContract>(books,
                LibraryContractsHostAdapters.BookInfoHostAdapter.ViewToContractAdapter,
                LibraryContractsHostAdapters.BookInfoHostAdapter.ContractToViewAdapter));
        }
    
        public override LibraryContractsHAV.BookInfo GetBestSeller()
        {
            return BookInfoHostAdapter.ContractToViewAdapter(_contract.GetBestSeller());
        }
    
        internal Library.ILibraryManagerContract GetSourceContract()
        {
            return _contract;
        }
        public override string Data(string txt)
        {
            string rtxt = _contract.Data(txt);
            return rtxt;
        }
    }
    }
    
  9. Use o código a seguir para adicionar o BookInfoHostAdapter classe para o HostSideAdaptersprojeto .A classe contém dois static () métodosShared métodos no Visual Basic): ContractToViewAdapter e ViewToContractAdapter.Os métodos são internal (Friend no Visual Basic) porque eles são usados somente por outras classes de adaptador. A finalidade desses métodos é evitar a criação de um adaptador extra quando um objeto faz uma viagem de ida e volta em qualquer direção entre o host e o suplemento.Esses métodos devem ser fornecidos para adaptadores que passam objetos entre o limite de isolamento.

    Imports Microsoft.VisualBasic
    Imports System
    Namespace LibraryContractsHostAdapters
    Public Class BookInfoHostAdapter
    
    Friend Shared Function ContractToViewAdapter(ByVal contract As Library.IBookInfoContract) As LibraryContractsHAV.BookInfo
        If Not System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(contract) AndAlso _
            CType(contract, Object).GetType().Equals(GetType(BookInfoViewToContractHostAdapter)) Then
            Return (CType(contract, BookInfoViewToContractHostAdapter)).GetSourceView()
        Else
            Return New BookInfoContractToViewHostAdapter(contract)
        End If
    End Function
    
    Friend Shared Function ViewToContractAdapter(ByVal view As LibraryContractsHAV.BookInfo) As Library.IBookInfoContract
        If Not System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(view) AndAlso _
            view.GetType().Equals(GetType(BookInfoContractToViewHostAdapter)) Then
            Return (CType(view, BookInfoContractToViewHostAdapter)).GetSourceContract()
        Else
            Return New BookInfoViewToContractHostAdapter(view)
        End If
    End Function
    End Class
    End Namespace
    
    using System;
    namespace LibraryContractsHostAdapters
    {
    public class BookInfoHostAdapter
    {
    
        internal static LibraryContractsHAV.BookInfo ContractToViewAdapter(Library.IBookInfoContract contract)
        {
            if (!System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(contract) &&
                (contract.GetType().Equals(typeof(BookInfoViewToContractHostAdapter))))
            {
                return ((BookInfoViewToContractHostAdapter)(contract)).GetSourceView();
    
            }
            else {
                return new BookInfoContractToViewHostAdapter(contract);
            }
        }
    
        internal static Library.IBookInfoContract ViewToContractAdapter(LibraryContractsHAV.BookInfo view)
        {
            if (!System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(view) &&
                (view.GetType().Equals(typeof(BookInfoContractToViewHostAdapter))))
            {
                return ((BookInfoContractToViewHostAdapter)(view)).GetSourceContract();
            }
            else {
                return new BookInfoViewToContractHostAdapter(view);
            }
        }
    }
    }
    

Criando o host

Um aplicativo host interage com o suplemento por meio do modo de exibição do host.Ele usa o suplemento detecção e ativação métodos fornecidos pelo AddInStore e AddInToken classes para fazer o seguinte:

  • Reconstrua o cache de informações de pipeline e o suplemento.

  • Localizar suplementos do tipo LibraryManager no diretório raiz do pipeline especificado.

  • Solicita que o usuário selecionar o suplemento para usar.Neste exemplo, apenas um suplemento está disponível.

  • Ative o suplemento selecionado em um novo domínio do aplicativo com um nível de confiança de segurança especificado.

  • Chamar o ProcessBooks método para passar uma coleção de BookInfo objetos para o suplemento. O suplemento chama sua implementação do ProcessBooks método e executa funções sistema autônomo livros de informática em 20 % de desconto.

  • Chama o GetBestSeller método que o suplemento usa para retornar uma BookInfo objeto com informações sobre o livro mais vendido.

  • Chama o Data método para obter a taxa corrente de imposto sobre vendas do suplemento. Esse método leva e retorna uma seqüência de caracteres que é um tipo de referência serializável lacrado.sistema autônomo resultado, o método pode ser passado sobre o isolamento de limite para o Outros lado do canal sem usar tipo exibição-para-contrato ou contrato-para-exibição adaptadores.

O host tem um CreateBooks método que cria uma coleção de BookInfo objetos. Esse método cria a coleção usando o arquivo de exemplo books.xml está disponível a partir de Sample XML File (books.xml).

Para criar o host

  1. Adicionar um novo projeto denominado Livraria to the BooksPipeline solução.Basear o Aplicativo de console modelo.

  2. No Visual Basic, abra o Propriedades para o projeto e utilize o Aplicativo guia para excluir o valor padrão fornecido para Namespace raiz.

  3. In O gerenciador de soluções, adicione uma referência ao assembly sistema.AddIn.dll para o Livrariaprojeto .

  4. Adicionar uma referência de projeto para o HostViews projeto. A referência Propriedades, conjunto Copiar local to False para essa referência, para impedir que o assembly mencionado sejam copiadas para a pasta local de compilação.

  5. No Visual Basic, alterar o módulo a uma classe:

    • Excluir o módulo padrão do projeto e, em seguida, adicione uma classe chamada Program.

    • Substitua o Public palavra-chave com o Friend palavra-chave.

    • Adicionar um Shared Sub Main() procedimento para a classe.

    • Use o Aplicativo Guia de do Propriedades do projeto caixa de diálogo conjuntoObjeto de inicialização to Sub Main.

  6. No arquivo classe, adicione referências para o System.AddIn.Pipeline e o host exiba namespaces de segmento.

  7. In O gerenciador de soluções, selecionar a solução e a partir de Projeto escolher de menu Propriedades.No Solução propriedade Pages caixa de diálogo, defina o Projeto de inicialização único para este projeto de aplicativo host.

  8. Use o seguinte código no aplicativo host.

    Observação:

    No código, alterar o local do qual o Books.XML arquivo é carregado para "books.xml", para que carrega o arquivo de pasta do aplicativo.Se você deseja colocar o aplicativo em um local diferente do Pipeline pasta, altere a linha de código que define o addInRoot variável para que a variável contém o caminho para sua estrutura de diretório do pipeline.

    Imports Microsoft.VisualBasic
    Imports System
    Imports System.Collections.Generic
    Imports System.Collections.ObjectModel
    Imports System.Text
    Imports LibraryContractsHAV
    Imports System.AddIn.Hosting
    Imports System.Xml
    
    
    Namespace ListAdaptersHost
    Friend Class Program
    Shared Sub Main(ByVal args As String())
    
        ' In this example, the pipeline root is the current directory.
        Dim pipeRoot As String = Environment.CurrentDirectory
    
        ' Rebuild the cache of pipeline and add-in information.
        Dim warnings As String() = AddInStore.Update(pipeRoot)
        If warnings.Length > 0 Then
            For Each one As String In warnings
                Console.WriteLine(one)
            Next one
        End If
    
        ' Find add-ins of type LibraryManager under the specified pipeline root directory.
        Dim tokens As Collection(Of AddInToken) = AddInStore.FindAddIns(GetType(LibraryManager), pipeRoot)
        ' Determine which add-in to use.
        Dim selectedToken As AddInToken = ChooseAddIn(tokens)
    
        ' Activate the selected AddInToken in a new
        ' application domain with a specified security trust level.
        Dim manager As LibraryManager = selectedToken.Activate(Of LibraryManager)(AddInSecurityLevel.FullTrust)
    
        ' Create a collection of books.
        Dim books As IList(Of BookInfo) = CreateBooks()
    
        ' Show the collection count.
        Console.WriteLine("Number of books:  {0}",books.Count.ToString())
    
        ' Have the add-in process the books.
        ' The add-in will discount computer books by $20
        ' and list their before and after prices. It
        ' will also remove all horror books.
        manager.ProcessBooks(books)
    
        ' List the genre of each book. There
        ' should be no horror books.
        For Each bk As BookInfo In books
            Console.WriteLine(bk.Genre())
        Next bk
    
        Console.WriteLine("Number of books: {0}", books.Count.ToString())
    
        Console.WriteLine()
        ' Have the add-in pass a BookInfo object
        ' of the best selling book.
        Dim bestBook As BookInfo = manager.GetBestSeller()
        Console.WriteLine("Best seller is {0} by {1}", bestBook.Title(), bestBook.Author())
    
        ' Have the add-in show the sales tax rate.
        manager.Data("sales tax")
    
        Dim ctrl As AddInController = AddInController.GetAddInController(manager)
        ctrl.Shutdown()
        Console.WriteLine("Press any key to exit.")
        Console.ReadLine()
    End Sub
    
    
    
    Private Shared Function ChooseAddIn(ByVal tokens As Collection(Of AddInToken)) As AddInToken
        If tokens.Count = 0 Then
            Console.WriteLine("No add-ins of this type are available")
            Return Nothing
        End If
        Console.WriteLine("{0} Available add-in(s):",tokens.Count.ToString())
        For i As Integer = 0 To tokens.Count - 1
            ' Show AddInToken properties.
            Console.WriteLine("[{0}] - {1}, Publisher: {2}, Version: {3}, Description: {4}", (i + 1).ToString(), tokens(i).Name, tokens(i).Publisher, tokens(i).Version, tokens(i).Description)
        Next i
        Console.WriteLine("Select add-in by number:")
        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 ChooseAddIn(tokens)
    End Function
    
    
    Friend Shared Function CreateBooks() As IList(Of BookInfo)
        Dim books As List(Of BookInfo) = New List(Of BookInfo)()
    
        Dim ParamId As String = ""
        Dim ParamAuthor As String = ""
        Dim ParamTitle As String = ""
        Dim ParamGenre As String = ""
        Dim ParamPrice As String = ""
        Dim ParamPublish_Date As String = ""
        Dim ParamDescription As String = ""
    
        Dim xDoc As XmlDocument = New XmlDocument()
        xDoc.Load("c:\Books.xml")
    
         Dim xRoot As XmlNode = xDoc.DocumentElement
         If xRoot.Name = "catalog" Then
            Dim bklist As XmlNodeList = xRoot.ChildNodes
            For Each bk As XmlNode In bklist
                ParamId = bk.Attributes(0).Value
                Dim dataItems As XmlNodeList = bk.ChildNodes
                Dim items As Integer = dataItems.Count
                For Each di As XmlNode In dataItems
                    Select Case di.Name
                        Case "author"
                            ParamAuthor = di.InnerText
                        Case "title"
                            ParamTitle = di.InnerText
                        Case "genre"
                            ParamGenre = di.InnerText
                         Case "price"
                            ParamPrice = di.InnerText
                         Case "publish_date"
                            ParamAuthor = di.InnerText
                         Case "description"
                            ParamDescription = di.InnerText
                          Case Else
                    End Select
    
                Next di
                books.Add(New MyBookInfo(ParamId, ParamAuthor, ParamTitle, ParamGenre, ParamPrice, ParamPublish_Date, ParamDescription))
            Next bk
    
         End If
        Return books
    End Function
    
    
    End Class
    
    Friend Class MyBookInfo
        Inherits BookInfo
        Private _id As String
        Private _author As String
        Private _title As String
        Private _genre As String
        Private _price As String
        Private _publish_date As String
        Private _description As String
    
        Public Sub New(ByVal id As String, ByVal author As String, ByVal title As String, ByVal genre As String, ByVal price As String, ByVal publish_date As String, ByVal description As String)
            _id = id
            _author = author
            _title = title
            _genre = genre
            _price = price
            _publish_date = publish_date
            _description = description
        End Sub
    
        Public Overrides Function ID() As String
            Return _id
        End Function
    
        Public Overrides Function Title() As String
            Return _title
        End Function
    
        Public Overrides Function Author() As String
            Return _author
        End Function
    
         Public Overrides Function Genre() As String
            Return _genre
         End Function
        Public Overrides Function Price() As String
            Return _price
        End Function
        Public Overrides Function Publish_Date() As String
            Return _publish_date
        End Function
        Public Overrides Function Description() As String
            Return _description
        End Function
    End Class
    End Namespace
    
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Text;
    using LibraryContractsHAV;
    using System.AddIn.Hosting;
    using System.Xml;
    
    
    namespace ListAdaptersHost
    {
    class Program
    {
    static void Main(string[] args)
    {
    
        // In this example, the pipeline root is the current directory.
        String pipeRoot = Environment.CurrentDirectory;
    
        // Rebuild the cache of pipeline and add-in information.
        string[] warnings = AddInStore.Update(pipeRoot);
        if (warnings.Length > 0)
        {
            foreach (string one in warnings)
            {
                Console.WriteLine(one);
            }
        }
    
        // Find add-ins of type LibraryManager under the specified pipeline root directory.
        Collection<AddInToken> tokens = AddInStore.FindAddIns(typeof(LibraryManager), pipeRoot);
        // Determine which add-in to use.
        AddInToken selectedToken = ChooseAddIn(tokens);
    
        // Activate the selected AddInToken in a new
        // application domain with a specified security trust level.
        LibraryManager manager = selectedToken.Activate<LibraryManager>(AddInSecurityLevel.FullTrust);
    
        // Create a collection of books.
        IList<BookInfo> books = CreateBooks();
    
        // Show the collection count.
        Console.WriteLine("Number of books:  {0}",books.Count.ToString());
    
        // Have the add-in process the books.
        // The add-in will discount computer books by $20
        // and list their before and after prices. It
        // will also remove all horror books.
        manager.ProcessBooks(books);
    
        // List the genre of each book. There
        // should be no horror books.
        foreach (BookInfo bk in books)
        {
            Console.WriteLine(bk.Genre());
        }
    
        Console.WriteLine("Number of books: {0}", books.Count.ToString());
    
        Console.WriteLine();
        // Have the add-in pass a BookInfo object
        // of the best selling book.
        BookInfo bestBook = manager.GetBestSeller();
        Console.WriteLine("Best seller is {0} by {1}", bestBook.Title(), bestBook.Author());
    
        // Have the add-in show the sales tax rate.
        manager.Data("sales tax");
    
        AddInController ctrl = AddInController.GetAddInController(manager);
        ctrl.Shutdown();
        Console.WriteLine("Press any key to exit.");
        Console.ReadLine();
    }
    
    
    
    private static AddInToken ChooseAddIn(Collection<AddInToken> tokens)
    {
        if (tokens.Count == 0)
        {
            Console.WriteLine("No add-ins of this type are available");
            return null;
        }
        Console.WriteLine("{0} Available add-in(s):",tokens.Count.ToString());
        for (int i = 0; i < tokens.Count; i++)
        {
            // Show AddInToken properties.
            Console.WriteLine("[{0}] - {1}, Publisher: {2}, Version: {3}, Description: {4}",
                (i + 1).ToString(), tokens[i].Name, tokens[i].Publisher,
                tokens[i].Version, tokens[i].Description);
        }
        Console.WriteLine("Select add-in by number:");
        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 ChooseAddIn(tokens);
    }
    
    
    internal static IList<BookInfo> CreateBooks()
    {
        List<BookInfo> books = new List<BookInfo>();
    
        string ParamId = "";
        string ParamAuthor = "";
        string ParamTitle = "";
        string ParamGenre = "";
        string ParamPrice = "";
        string ParamPublish_Date = "";
        string ParamDescription = "";
    
        XmlDocument xDoc = new XmlDocument();
        xDoc.Load(@"c:\Books.xml");
    
         XmlNode xRoot = xDoc.DocumentElement;
         if (xRoot.Name == "catalog")
        {
            XmlNodeList bklist = xRoot.ChildNodes;
            foreach (XmlNode bk in bklist)
            {
                ParamId = bk.Attributes[0].Value;
                XmlNodeList dataItems = bk.ChildNodes;
                int items = dataItems.Count;
                foreach (XmlNode di in dataItems)
                {
                    switch (di.Name)
                    {
                        case "author":
                            ParamAuthor = di.InnerText;
                            break;
                        case "title":
                            ParamTitle = di.InnerText;
                            break;
                        case "genre":
                            ParamGenre = di.InnerText;
                            break;
                         case "price":
                            ParamPrice = di.InnerText;
                            break;
                         case "publish_date":
                            ParamAuthor = di.InnerText;
                            break;
                         case "description":
                            ParamDescription = di.InnerText;
                            break;
                          default:
                            break;
                    }
    
                }
                books.Add(new MyBookInfo(ParamId, ParamAuthor, ParamTitle, ParamGenre,
                                ParamPrice, ParamPublish_Date, ParamDescription));
            }
    
        }
        return books;
    }
    
    
    }
    
    class MyBookInfo : BookInfo
    {
        private string _id;
        private string _author;
        private string _title;
        private string _genre;
        private string _price;
        private string _publish_date;
        private string _description;
    
        public MyBookInfo(string id, string author, string title,
                            string genre, string price,
                            string publish_date, string description)
        {
            _id = id;
            _author = author;
            _title = title;
            _genre = genre;
            _price = price;
            _publish_date = publish_date;
            _description = description;
        }
    
        public override string ID()
        {
            return _id;
        }
    
        public override string Title()
        {
            return _title;
        }
    
        public override string Author()
        {
            return _author;
        }
    
         public override string Genre()
        {
            return _genre;
        }
        public override string Price()
        {
            return _price;
        }
        public override string Publish_Date()
        {
            return _publish_date;
        }
        public override string Description()
        {
            return _description;
        }
    }
    }
    

Para criar o arquivo de dados do books.xml

  1. Adicionar um novo arquivo XML para o Livrariaprojeto .No Adicionar novo item caixa de diálogo, o arquivo nomeBooks.XML.

  2. Substituir o Sumário padrão de Books.XML com o XML de Sample XML File (books.xml).

  3. No gerenciador de soluções, selecionar Books.XML, and in Propriedades conjunto Copiar para diretório de saída to Copiar sempre.

Criando o suplemento

Um suplemento implementa os métodos especificados pelo exibição de suplemento.Este suplemento implementa o ProcessBooks método. O método executa as seguintes operações em uma coleção de BookInfo objetos que o host passa para ele:

  • Descontos o preço de todos os livros de informática em 20 por cento.

  • Remove todos os livros de terror da coleção.

Este suplemento também implementa o GetBestSeller método passando um BookInfo objeto que descreve o catálogo mais vendido para o host.

Para criar o suplemento

  1. Adicionar um novo projeto denominado BooksAddin to the BooksPipeline solução.Basear o biblioteca de classes modelo.

  2. No Visual Basic, abra o Propriedades para o projeto e utilize o Aplicativo guia para excluir o valor padrão fornecido para Namespace raiz.

  3. In O gerenciador de soluções, adicione uma referência ao assembly sistema.AddIn.dll para o BooksAddinprojeto .

  4. Adicionar uma referência de projeto para o AddInViewsprojeto .A referência Propriedades, conjunto Copiar local to False para essa referência, para impedir que o assembly mencionado sejam copiadas para a pasta local de compilação.

  5. No arquivo classe, adicione referências para o System.AddIn e os espaços para nome do suplemento no modo de exibição segmento.

  6. Use o seguinte código para o aplicativo suplemento.

    Imports Microsoft.VisualBasic
    Imports System
    Imports System.Collections.Generic
    Imports System.Text
    Imports LibraryContractsBase
    Imports System.AddIn
    Imports System.IO
    
    Namespace SampleAddIn
    <AddIn("Books AddIn",Version:="1.0.0.0")> _
    Public Class BooksAddIn
        Inherits LibraryManager
        ' Calls methods that updates book data
        ' and removes books by genre.
        Public Overrides Sub ProcessBooks(ByVal books As IList(Of BookInfo))
            For i As Integer = 0 To books.Count - 1
                books(i) = UpdateBook(books(i))
            Next i
            RemoveGenre("horror", books)
        End Sub
    
        Public Overrides Function Data(ByVal txt As String) As String
            ' assumes txt = "sales tax"
            Dim rtxt As String = txt & "= 8.5%"
            Return rtxt
        End Function
    
        Friend Shared Function RemoveGenre(ByVal genre As String, ByVal books As IList(Of BookInfo)) As IList(Of BookInfo)
            ' Remove all horror books from the collection.
            Dim i As Integer = 0
            Do While i < books.Count
                If books(i).Genre().ToLower() = "horror" Then
                    books.RemoveAt(i)
                End If
                i += 1
            Loop
            Return books
        End Function
    
        ' Populate a BookInfo object with data
        ' about the best selling book.
        Public Overrides Function GetBestSeller() As BookInfo
            Dim ParamId As String = "bk999"
            Dim ParamAuthor As String = "Corets, Eva"
            Dim ParamTitle As String = "Cooking with Oberon"
            Dim ParamGenre As String = "Cooking"
            Dim ParamPrice As String = "7.95"
            Dim ParamPublish_Date As String = "2006-12-01"
            Dim ParamDescription As String = "Recipes for a post-apocalyptic society."
    
            Dim bestBook As MyBookInfo = New MyBookInfo(ParamId, ParamAuthor, ParamTitle, ParamGenre, ParamPrice, ParamPublish_Date, ParamDescription)
            Return bestBook
        End Function
    
        Friend Shared Function UpdateBook(ByVal bk As BookInfo) As BookInfo
            ' Discounts the price of all
            ' computer books by 20 percent.
            Dim ParamId As String = bk.ID()
            Dim ParamAuthor As String = bk.Author()
            Dim ParamTitle As String = bk.Title()
            Dim ParamGenre As String = bk.Genre()
            Dim ParamPrice As String = bk.Price()
            If ParamGenre.ToLower() = "computer" Then
                Dim oldprice As Double = Convert.ToDouble(ParamPrice)
                Dim newprice As Double = oldprice - (oldprice *.20)
                ParamPrice = newprice.ToString()
                If ParamPrice.IndexOf(".") = ParamPrice.Length - 4 Then
                    ParamPrice = ParamPrice.Substring(1, ParamPrice.Length - 1)
                End If
                Console.WriteLine("{0} - Old Price: {1}, New Price: {2}",ParamTitle,oldprice.ToString(),ParamPrice)
            End If
            Dim ParamPublish_Date As String = bk.Publish_Date()
            Dim ParamDescription As String = bk.Description()
    
            Dim bookUpdated As BookInfo = New MyBookInfo(ParamId, ParamAuthor, ParamTitle, ParamGenre, ParamPrice, ParamPublish_Date, ParamDescription)
    
            Return bookUpdated
    
        End Function
    
    End Class
    
    ' Creates a BookInfo object.
    Friend Class MyBookInfo
        Inherits BookInfo
        Private _id As String
        Private _author As String
        Private _title As String
        Private _genre As String
        Private _price As String
        Private _publish_date As String
        Private _description As String
    
        Public Sub New(ByVal id As String, ByVal author As String, ByVal title As String, ByVal genre As String, ByVal price As String, ByVal publish_date As String, ByVal description As String)
            _id = id
            _author = author
            _title = title
            _genre = genre
            _price = price
            _publish_date = publish_date
            _description = description
        End Sub
    
        Public Overrides Function ID() As String
            Return _id
        End Function
    
        Public Overrides Function Title() As String
            Return _title
        End Function
    
        Public Overrides Function Author() As String
            Return _author
        End Function
    
        Public Overrides Function Genre() As String
            Return _genre
        End Function
        Public Overrides Function Price() As String
            Return _price
        End Function
        Public Overrides Function Publish_Date() As String
            Return _publish_date
        End Function
        Public Overrides Function Description() As String
            Return _description
        End Function
    End Class
    
    End Namespace
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using LibraryContractsBase;
    using System.AddIn;
    using System.IO;
    
    namespace BooksAddIn
    {
    [AddIn("Books AddIn",Description="Book Store Data",
           Publisher="Microsoft",Version="1.0.0.0")]
    
    public class BooksAddIn : LibraryManager
    {
        // Calls methods that updates book data
        // and removes books by their genre.
        public override void ProcessBooks(IList<BookInfo> books)
        {
            for (int i = 0; i < books.Count; i++)
            {
                books[i] = UpdateBook(books[i]);
            }
            RemoveGenre("horror", books);
        }
    
        public override string Data(string txt)
        {
            // assumes txt = "sales tax"
            string rtxt = txt + "= 8.5%";
            return rtxt;
        }
    
        internal static IList<BookInfo> RemoveGenre(string genre, IList<BookInfo> books)
        {
            // Remove all horror books from the collection.
            for (int i = 0; i < books.Count; i++)
            {
                if (books[i].Genre().ToLower() == "horror")
                    books.RemoveAt(i);
            }
            return books;
        }
    
        // Populate a BookInfo object with data
        // about the best selling book.
        public override BookInfo GetBestSeller()
        {
            string ParamId = "bk999";
            string ParamAuthor = "Corets, Eva";
            string ParamTitle = "Cooking with Oberon";
            string ParamGenre = "Cooking";
            string ParamPrice = "7.95";
            string ParamPublish_Date = "2006-12-01";
            string ParamDescription = "Recipes for a post-apocalyptic society.";
    
            MyBookInfo bestBook = new MyBookInfo(ParamId, ParamAuthor, ParamTitle, ParamGenre,
                                    ParamPrice, ParamPublish_Date, ParamDescription);
            return bestBook;
        }
    
        internal static BookInfo UpdateBook(BookInfo bk)
        {
            // Discounts the price of all
            // computer books by 20 percent.
            string ParamId = bk.ID();
            string ParamAuthor = bk.Author();
            string ParamTitle = bk.Title();
            string ParamGenre = bk.Genre();
            string ParamPrice = bk.Price();
            if (ParamGenre.ToLower() == "computer")
            {
                double oldprice = Convert.ToDouble(ParamPrice);
                double newprice = oldprice - (oldprice * .20);
                ParamPrice = newprice.ToString();
                if (ParamPrice.IndexOf(".") == ParamPrice.Length - 4)
                    ParamPrice = ParamPrice.Substring(1, ParamPrice.Length - 1);
                Console.WriteLine("{0} - Old Price: {1}, New Price: {2}",ParamTitle,oldprice.ToString(),ParamPrice);
            }
            string ParamPublish_Date = bk.Publish_Date();
            string ParamDescription = bk.Description();
    
            BookInfo bookUpdated = new MyBookInfo(ParamId, ParamAuthor, ParamTitle, ParamGenre,
                            ParamPrice, ParamPublish_Date, ParamDescription);
    
            return bookUpdated;
    
        }
    
    }
    
    // Creates a BookInfo object.
    class MyBookInfo : BookInfo
    {
        private string _id;
        private string _author;
        private string _title;
        private string _genre;
        private string _price;
        private string _publish_date;
        private string _description;
    
        public MyBookInfo(string id, string author, string title,
                            string genre, string price,
                            string publish_date, string description)
        {
            _id = id;
            _author = author;
            _title = title;
            _genre = genre;
            _price = price;
            _publish_date = publish_date;
            _description = description;
        }
    
        public override string ID()
        {
            return _id;
        }
    
        public override string Title()
        {
            return _title;
        }
    
        public override string Author()
        {
            return _author;
        }
    
        public override string Genre()
        {
            return _genre;
        }
        public override string Price()
        {
            return _price;
        }
        public override string Publish_Date()
        {
            return _publish_date;
        }
        public override string Description()
        {
            return _description;
        }
    }
    
    }
    

Implantando o pipeline

Agora você está pronto para compilação e implantar os segmentos do suplemento para a estrutura de diretório do pipeline necessários.

Para distribuir os segmentos para o pipeline

  1. Para cada projeto na solução, use o Compilação tab of Propriedades do projeto (the Compilar guia no Visual Basic) para conjunto o valor do Caminho de saída (the Construir o caminho de saída no Visual Basic) sistema autônomo mostrado na tabela seguinte.

    Project

    Caminho

    BooksAddIn

    Pipeline\AddIns\CalcV1

    AddInSideAdapters

    Pipeline\AddInSideAdapters

    AddInViews

    Pipeline\AddInViews

    LibraryContracts

    Pipeline\Contracts

    Livraria

    Pipeline (ou seu próprio diretório de aplicativo)

    HostSideAdapters

    Pipeline\HostSideAdapters

    HostViews

    Pipeline (ou seu próprio diretório de aplicativo)

    Observação:

    Se decidir colocar seu aplicativo em um local diferente de Pipeline pasta, certifique-se de alterar o código de host que especifica o local da diretório raiz do pipeline.

  2. Crie a solução do Visual Studio.

    Para obter informações sobre a implantação no pipeline, consulte Requisitos de desenvolvimento de pipeline.

Executando o aplicativo host

Agora você está pronto para executar o host e interagir com o suplemento.

Para executar aplicativo host

  1. No aviso de comando, vá para o diretório raiz do pipeline e execute o aplicativo host.Neste exemplo, o aplicativo host é BookStore.exe.

  2. Ele localiza todos os suplementos disponível do seu tipo e solicita que você selecionar um suplemento.Digite 1 para o suplemento só está disponível.

    O host ativa o suplemento e usa-lo para executar diversas operações na lista de livros.

  3. Pressione qualquer tecla para fechar o aplicativo.

Consulte também

Tarefas

Demonstra Passo a passo: Criando um aplicativo extensível

Demonstra Passo a passo: Ativar compatibilidade com versões anteriores, sistema autônomo sistema autônomo alterações de host

Conceitos

Requisitos de desenvolvimento de pipeline

Contratos, exibições e adaptadores

Desenvolvimento de pipeline

Date

History

Motivo

Julho de 2008

Fixos erros no texto.Adicionar uma observação sobre como manter uma referência ao contrato.

Comentários do cliente.