Compartilhar via


PCL (Bibliotecas de classe portáteis)

Dica

Bibliotecas de classes portáteis (PCLs) são consideradas obsoletas nas versões mais recentes do Visual Studio. Embora você ainda possa abrir, editar e compilar PCLs, para novos projetos é recomendável usar bibliotecas do .NET Standard para acessar uma área de superfície de API maior.

Um componente-chave da criação de aplicativos de plataforma cruzada é ser capaz de compartilhar código em vários projetos específicos da plataforma. No entanto, isso é complicado pelo fato de que plataformas diferentes geralmente usam um subconjunto diferente da BCL (Biblioteca de Classes Base) do .NET e, portanto, são criadas para um Perfil de Biblioteca do .NET Core diferente. Isso significa que cada plataforma só pode usar bibliotecas de classes direcionadas ao mesmo perfil, portanto, elas parecem exigir projetos de biblioteca de classes separados para cada plataforma.

Há três abordagens principais para o compartilhamento de código que abordam esse problema: projetos do .NET Standard, projetos de ativos compartilhados e projetos de biblioteca de classes portátil (PCL).

  • Projetos do .NET Standard são a abordagem preferida para compartilhar código .NET, leia mais sobre projetos do .NET Standard e Xamarin.
  • Projetos de ativos compartilhados usam um único conjunto de arquivos e oferecem uma maneira rápida e simples de compartilhar código dentro de uma solução e geralmente empregam diretivas de compilação condicional para especificar caminhos de código para várias plataformas que o usarão (para obter mais informações, consulte o artigo Projetos compartilhados).
  • Os projetos PCL destinam-se a perfis específicos que oferecem suporte a um conjunto conhecido de classes/recursos BCL. No entanto, a desvantagem da PCL é que elas geralmente exigem esforço arquitetônico extra para separar o código específico do perfil em suas próprias bibliotecas.

Esta página explica como criar um projeto PCL direcionado a um perfil específico, que pode ser referenciado por vários projetos específicos da plataforma.

O que é uma Biblioteca de Classes Portátil?

Quando você cria um projeto de aplicativo ou um projeto de biblioteca, a DLL resultante é restrita a trabalhar na plataforma específica para a qual foi criada. Isso impede que você escreva um assembly para um aplicativo do Windows e, em seguida, reutilize-o no Xamarin.iOS e Xamarin.Android.

No entanto, ao criar uma Biblioteca de Classes Portátil, você pode escolher uma combinação de plataformas nas quais deseja que seu código seja executado. As opções de compatibilidade feitas ao criar uma Biblioteca de Classes Portátil são convertidas em um identificador "Perfil", que descreve quais plataformas a biblioteca suporta.

A tabela abaixo mostra alguns dos recursos que variam de acordo com a plataforma .NET. Para escrever um assembly PCL que é garantido para executar em dispositivos/plataformas específicos, basta escolher qual suporte é necessário ao criar o projeto.

Recurso .NET Framework Aplicativos UWP Silverlight Windows Phone Xamarin
Núcleo N N N N S
LINQ N N N N S
IQueryable N N S 7.5+ Y
Serialização N N N N S
Anotações de dados 4.0.3 + N N S

A coluna Xamarin reflete o fato de que o Xamarin.iOS e o Xamarin.Android oferecem suporte a todos os perfis fornecidos com o Visual Studio, e a disponibilidade de recursos em quaisquer bibliotecas criadas será limitada apenas pelas outras plataformas que você escolher suportar.

Isso inclui perfis que são combinações de:

  • .NET 4 ou .NET 4.5
  • Silverlight 5
  • Windows Phone 8
  • Aplicativos UWP

Você pode ler mais sobre os recursos dos diferentes perfis no site da Microsoft e ver o resumo do perfil PCL de outro membro da comunidade, que inclui informações de estrutura com suporte e outras notas.

Benefícios

  1. Compartilhamento centralizado de código – escreva e teste código em um único projeto que pode ser consumido por outras bibliotecas ou aplicativos.
  2. As operações de refatoração afetarão todo o código carregado na solução (a Biblioteca de Classes Portátil e os projetos específicos da plataforma).
  3. O projeto PCL pode ser facilmente referenciado por outros projetos em uma solução, ou o assembly de saída pode ser compartilhado para que outros façam referência em suas soluções.

Desvantagens

  1. Como a mesma Biblioteca de Classes Portátil é compartilhada entre vários aplicativos, bibliotecas específicas da plataforma não podem ser referenciadas (por exemplo. Comunidade.CsharpSqlite.WP7).
  2. O subconjunto Biblioteca de classes portátil pode não incluir classes que, de outra forma, estariam disponíveis no MonoTouch e no Mono para Android (como DllImport ou System.IO.File).

Observação

Bibliotecas de classes portáteis foram preteridas na versão mais recente do Visual Studio, e bibliotecas padrão .NET são recomendadas em vez disso.

Até certo ponto, ambas as desvantagens podem ser contornadas usando o padrão Provider ou Dependency Injection para codificar a implementação real nos projetos de plataforma em relação a uma interface ou classe base definida na Biblioteca de Classes Portátil.

Este diagrama mostra a arquitetura de um aplicativo de plataforma cruzada usando uma Biblioteca de Classes Portátil para compartilhar código, mas também usando a Injeção de Dependência para passar recursos dependentes da plataforma:

Este diagrama mostra a arquitetura de um aplicativo de plataforma cruzada usando uma Biblioteca de Classes Portátil para compartilhar código, mas também usando a Injeção de Dependência para passar recursos dependentes da plataforma

Passo a passo do Visual Studio para Mac

Esta seção explica como criar e usar uma biblioteca de classes portátil usando o Visual Studio para Mac. Consulte a seção Exemplo de PCL para obter uma implementação completa.

Criando uma PCL

Adicionar uma Biblioteca de Classes Portátil à sua solução é muito semelhante a adicionar um projeto de Biblioteca normal.

  1. Na caixa de diálogo Novo Projeto, selecione a opção Biblioteca Portátil Multiplataforma > >:

    Criar um novo projeto PCL

  2. Quando uma PCL é criada no Visual Studio para Mac, ela é configurada automaticamente com um perfil que funciona para Xamarin.iOS e Xamarin.Android. O projeto PCL aparecerá como mostrado nesta captura de tela:

    Projeto PCL no bloco de soluções

A PCL agora está pronta para o código ser adicionado. Ele também pode ser referenciado por outros projetos (projetos de aplicação, projetos de biblioteca e até mesmo outros projetos PCL).

Editando configurações de PCL

Para exibir e alterar as configurações de PCL para este projeto, clique com o botão direito do mouse no projeto e escolha Opções > de compilação > geral para ver a tela mostrada aqui:

Opções do projeto PCL para definir o perfil

Clique em Alterar... para alterar o perfil de destino desta biblioteca de classes portátil.

Se o perfil for alterado depois que o código já tiver sido adicionado à PCL, é possível que a biblioteca não seja mais compilada se o código fizer referência a recursos que não fazem parte do perfil recém-selecionado.

Trabalhando com uma PCL

Quando o código é escrito em uma biblioteca PCL, o editor do Visual Studio para Mac reconhecerá as limitações do perfil selecionado e ajustará as opções de preenchimento automático de acordo. Por exemplo, esta captura de tela mostra as opções de preenchimento automático para System.IO usando o perfil padrão (Profile136) usado no Visual Studio para Mac – observe a barra de rolagem que indica que cerca de metade das classes disponíveis são exibidas (na verdade, há apenas 14 classes disponíveis).

Lista do Intellisense de 14 classes na classe System.IO de uma PCL

Compare isso com o preenchimento automático System.IO em um projeto Xamarin.iOS ou Xamarin.Android – há 40 classes disponíveis, incluindo classes comumente usadas como File e Directory que não estão em nenhum perfil PCL.

Lista do Intellisense de 40 classes no namespace do .NET Framework System.IO

Isso reflete a compensação subjacente do uso da PCL – a capacidade de compartilhar código perfeitamente em muitas plataformas significa que certas APIs não estão disponíveis para você porque não têm implementações comparáveis em todas as plataformas possíveis.

Usando PCL

Depois que um projeto PCL tiver sido criado, você poderá adicionar uma referência a ele a partir de qualquer projeto de Aplicativo ou Biblioteca compatível da mesma forma que normalmente adiciona referências. No Visual Studio para Mac, clique com o botão direito do mouse no nó Referências e escolha Editar referências... e, em seguida, alterne para a guia Projetos, conforme mostrado:

Adicionar uma referência a uma PCL por meio da opção Editar referências

A captura de tela a seguir mostra o painel Solução para o aplicativo de exemplo TaskyPortable, mostrando a biblioteca PCL na parte inferior e uma referência a essa biblioteca PCL no projeto Xamarin.iOS.

Solução de exemplo TaskyPortable mostrando o projeto PCL

A saída de uma PCL (ou seja, a DLL de assembly resultante) também pode ser adicionada como referência à maioria dos projetos. Isso torna o PCL uma maneira ideal de enviar componentes e bibliotecas multiplataforma.

Exemplo de PCL

O aplicativo de exemplo TaskyPortable demonstra como uma biblioteca de classes portátil pode ser usada com o Xamarin. Aqui estão algumas capturas de tela dos aplicativos resultantes em execução no iOS e Android:

Aqui estão algumas capturas de tela dos aplicativos resultantes em execução no iOS, Android e Windows Phone

Ele compartilha uma série de dados e classes lógicas que são código puramente portátil e também demonstra como incorporar requisitos específicos da plataforma usando injeção de dependência para a implementação do banco de dados SQLite.

A estrutura da solução é mostrada abaixo (no Visual Studio para Mac e Visual Studio, respectivamente):

A estrutura da solução é mostrada aqui no Visual Studio para Mac e Visual Studio, respectivamente

Como o código SQLite-NET tem partes específicas da plataforma (para trabalhar com as implementações SQLite em cada sistema operacional diferente) para fins de demonstração, ele foi refatorado em uma classe abstrata que pode ser compilada em uma Biblioteca de Classes Portátil e o código real implementado como subclasses nos projetos iOS e Android.

TaskyPortableLibrary

A Biblioteca de Classes Portátil é limitada nos recursos do .NET que ela pode suportar. Como ele é compilado para ser executado em várias plataformas, ele não pode fazer uso da [DllImport] funcionalidade que é usada no SQLite-NET. Em vez disso, SQLite-NET é implementado como uma classe abstrata e, em seguida, referenciado através do resto do código compartilhado. Um extrato da API abstrata é mostrado abaixo:

public abstract class SQLiteConnection : IDisposable {

    public string DatabasePath { get; private set; }
    public bool TimeExecution { get; set; }
    public bool Trace { get; set; }
    public SQLiteConnection(string databasePath) {
         DatabasePath = databasePath;
    }
    public abstract int CreateTable<T>();
    public abstract SQLiteCommand CreateCommand(string cmdText, params object[] ps);
    public abstract int Execute(string query, params object[] args);
    public abstract List<T> Query<T>(string query, params object[] args) where T : new();
    public abstract TableQuery<T> Table<T>() where T : new();
    public abstract T Get<T>(object pk) where T : new();
    public bool IsInTransaction { get; protected set; }
    public abstract void BeginTransaction();
    public abstract void Rollback();
    public abstract void Commit();
    public abstract void RunInTransaction(Action action);
    public abstract int Insert(object obj);
    public abstract int Update(object obj);
    public abstract int Delete<T>(T obj);

    public void Dispose()
    {
        Close();
    }
    public abstract void Close();

}

O restante do código compartilhado usa a classe abstrata para "armazenar" e "recuperar" objetos do banco de dados. Em qualquer aplicativo que usa essa classe abstrata, devemos passar uma implementação completa que forneça a funcionalidade real do banco de dados.

TaskyAndroid e TaskyiOS

Os projetos de aplicativos iOS e Android contêm a interface do usuário e outro código específico da plataforma usado para conectar o código compartilhado na PCL.

Esses projetos também contêm uma implementação da API de banco de dados abstrato que funciona nessa plataforma. No iOS e Android, o mecanismo de banco de dados Sqlite é integrado ao sistema operacional, de modo que a implementação pode ser usada [DllImport] como mostrado para fornecer a implementação concreta da conectividade do banco de dados. Um trecho do código de implementação específico da plataforma é mostrado aqui:

[DllImport("sqlite3", EntryPoint = "sqlite3_open")]
public static extern Result Open(string filename, out IntPtr db);

[DllImport("sqlite3", EntryPoint = "sqlite3_close")]
public static extern Result Close(IntPtr db);

A implementação completa pode ser vista no código de exemplo.

Resumo

Este artigo discutiu brevemente os benefícios e as armadilhas das bibliotecas de classes portáteis, demonstrou como criar e consumir PCLs de dentro do Visual Studio para Mac e Visual Studio; e, finalmente, introduziu um aplicativo de amostra completo – TaskyPortable – que mostra uma PCL em ação.