André Alves de Lima

Talking about Software Development and more…

Utilizando uma biblioteca .NET Standard com Windows Forms e WPF

Algumas semanas atrás eu mostrei para você como instalar o .NET Core e criar o seu primeiro projeto “Hello World” com ele. Hoje eu quero mostrar para você algo relacionado. Será que nós conseguimos utilizar bibliotecas do .NET Core em projetos desktop? E o contrário? Será que nós conseguimos utilizar bibliotecas desenvolvidas com o .NET Framework em projetos .NET Core?

No artigo de hoje você aprenderá a utilizar bibliotecas .NET Standard com Windows Forms e WPF, ou seja, em projetos que utilizam o .NET Framework “full“.

Entendendo o .NET Standard

Antes de continuarmos, nós precisamos esclarecer alguns pontos. Muita gente acaba confundindo os conceitos de .NET Core e .NET Standard. Na verdade, ao contrário do que algumas pessoas acabam supondo, não é possível referenciar uma biblioteca .NET Core em projetos que tenham o .NET Framework “full” como target framework. O contrário também não é possível, ou seja, você não consegue referenciar bibliotecas desenvolvidas com o “full Framework” em projetos .NET Core.

Mas, então, como é possível compartilhar código entre projetos “full Framework” e .NET Core? É aí que entra em jogo o .NET Standard. Ele nada mais é que um padrão (ou especificação) que define uma lista de APIs a serem implementadas por uma versão do framework. Por exemplo, o .NET Framework 4.5 implementa as APIs definidas no .NET Standard 1.0. Por sua vez, o .NET Framework 4.6.1 implementa as APIs definidas no .NET Standard 2.0.

Neste link, você encontra a tabela mostrando todas as plataformas suportadas por cada uma das versões do .NET Standard. Veja abaixo essa tabela na sua versão de abril de 2018:

Eu não vou entrar em muitos detalhes sobre o .NET Standard porque outras pessoas já fizeram um excelente trabalho nesse quesito. Por exemplo, o Eduardo Pires já escreveu um artigo muito completo explicando todos os conceitos por trás do .NET Standard.

O ponto principal que precisa entrar na sua cabeça é que o .NET Standard não é uma implementação do .NET Framework em si, mas sim, uma especificação que as diversas versões do .NET Framework implementam. Ou seja, você não “instala” o .NET Standard, mas sim o .NET Framework (que por sua vez, implementa as APIs do .NET Standard).

Quando nós pensamos em compartilhamento de código (que é o ponto que eu quero ressaltar neste artigo), nós falamos de .NET Standard. Ou seja, para compartilharmos código entre as diversas plataformas do .NET Framework, nós temos que criar bibliotecas .NET Standard (o que era antigamente resolvido com as PCLs – Portable Class Libraries).

Criando os projetos de exemplo

Uma vez esclarecidos os pontos sobre .NET Framework “full“, .NET Core e .NET Standard, vamos começar criando normalmente o nosso projeto desktop. Nesse exemplo eu vou utilizar um projeto do tipo Windows Forms, porém, você poderia utilizar um projeto WPF sem problema nenhum. Todos os conceitos apresentados neste artigo valem para projetos WPF também.

O único detalhe importante que temos que nos atentar, é que nós precisamos utilizar o .NET Framework 4.6.1 para esse projeto. Isso porque, como dito anteriormente, o .NET Standard 2.0 (que utilizaremos nesse artigo) só é suportado por essa versão do .NET Framework:

Com o projeto criado, vamos ajustar o formulário para que ele fique parecido com a imagem abaixo:

A ideia é que, ao clicarmos no botão, nós vamos chamar um método em uma biblioteca que retornará um texto a ser exibido no TextBox. É um exemplo extremamente simples, mas que mostrará os conceitos por trás do compartilhamento de código através de bibliotecas .NET Standard.

Agora que nós já temos a interface ajustada, vamos criar um novo projeto do tipo “Class Library“, onde nós implementaremos o método que retornará um texto qualquer. A princípio, criaremos essa biblioteca utilizando o .NET Framework 4.6.1 (mais para a frente nós converteremos essa biblioteca para o .NET Standard):

Dentro do projeto “Class Library“, vamos ajustar o nome da classe “Class1” (alterando-o para “Classe“) e, além disso, vamos adicionar um método estático que retornará uma string:

    // C#
    public class Classe
    {
        public static string PegarString()
        {
            return "Conteúdo retornado pela biblioteca";
        }
    }
' VB.NET
Public Class Classe
    Public Shared Function PegarString() As String
        Return "Conteúdo retornado pela biblioteca"
    End Function
End Class

Em seguida, vamos voltar para o nosso projeto desktop, onde nós adicionaremos uma referência para o projeto da biblioteca:

Por fim, vamos implementar o código do clique do botão, que chamará o método “PegarString” e exibirá o resultado no TextBox:

        // C#
        private void preencherButton_Click(object sender, EventArgs e)
        {
            textBox1.Text = Biblioteca.Classe.PegarString();
        }
    ' VB.NET
    Private Sub preencherButton_Click(sender As Object, e As EventArgs) Handles preencherButton.Click
        textBox1.Text = Biblioteca.VB.NetStandard.Classe.PegarString()
    End Sub

Se executarmos a nossa aplicação, veremos que ela funcionará conforme esperado:

Adicionando um projeto .NET Core Console Application

Agora que nós já temos o projeto desktop funcionando corretamente com a biblioteca criada no .NET Framework “full“, vamos verificar se essa mesma biblioteca pode ser utilizada em um projeto .NET Core. Para testarmos isso, vamos criar um projeto do tipo “Console App (.NET Core)“:

Se adicionarmos uma referência à nossa biblioteca, surpreendentemente o projeto compilará sem problema nenhum. Agora vamos tentar acessar o nosso método para ver o que acontece:

        // C#
        static void Main(string[] args)
        {
            Console.WriteLine(Biblioteca.Classe.PegarString());
            Console.ReadLine();
        }
    ' VB.NET
    Sub Main(args As String())
        Console.WriteLine(Biblioteca.VB.NetStandard.Classe.PegarString())
        Console.ReadLine()
    End Sub

E não é que a aplicação funciona?

Sinceramente eu não sei qual é a lógica por trás disso, mas com alguma mágica por trás dos panos, o .NET Core entende que a biblioteca foi compilada para o .NET Framework 4.6.1 e, como o .NET Core 2.0 dá suporte ao .NET Standard 2.0 (que por sua vez dá suporte ao .NET 4.6.1), o .NET Core libera a utilização desse assembly.

Porém, temos um problema grave com isso. Como o nosso projeto desktop também foi compilado com o .NET Framework 4.6.1, nós conseguimos adicionar uma referência a ele também no nosso projeto .NET Core. O projeto compila normalmente, entretanto, se tentarmos acessar qualquer coisa que não for suportada pelo .NET Standard (por exemplo, um formulário), o projeto quebrará em tempo de execução com uma exceção:

Esse não é um comportamento legal, então, eu particularmente evitaria fazer esse tipo de referência. Ao invés disso, o ideal é converter a biblioteca em um projeto .NET Standard.

Convertendo uma biblioteca .NET Framework em .NET Standard

Para convertermos a nossa biblioteca do .NET Framework em .NET Standard, nós temos basicamente duas opções:

1 – Criar um novo projeto do tipo .NET Standard e copiar todo o código da biblioteca para dentro dele

2 – Utilizar uma ferramenta para converter o formato do .csproj de .NET Framework para .NET Standard

Como a biblioteca deste artigo é extremamente simples, nós poderíamos facilmente criar um novo projeto e adicionar o código da nossa única classe dentro desse novo projeto. Porém, para bibliotecas maiores, isso acaba ficando inviável. Nesse caso, nós podemos utilizar a ferramenta CsprojToVs2017 para fazer a conversão automática do tipo do projeto.

A utilização dessa ferramenta é muito simples. Basta chamar o executável “Project2015To2017.Console.exe” passando o caminho do arquivo .csproj e ele fará a conversão:

Nota: até o momento da escrita deste artigo, essa ferramenta só suporta arquivos .csproj, ou seja, não é possível converter projetos VB.NET. Nesse caso a única solução seria converter a biblioteca manualmente (criando outro projeto e migrando os arquivos). Os autores da biblioteca estão planejando implementar o suporte a arquivos .vbproj. Você pode acompanhar o andamento dessa questão através deste link.

Ao voltarmos para o Visual Studio, ele detectará as alterações no arquivo .csproj e perguntará se nós queremos recarrega-lo:

Uma vez recarregado, observe que o projeto já é exibido no Solution Explorer com o novo formato típico de projetos .NET Core / .NET Standard:

Porém, se nós tentarmos recompilar a solução, nós receberemos um erro:

Esse erro acontece porque, apesar da ferramenta ter convertido o formato do arquivo .csproj, ele ainda continua com o Target Framework configurado para a versão .NET Framework 4.6.1. Para alterarmos isso, nós temos que editar o arquivo .csproj e, dentro da tag “TargetFramework“, nós temos que alterar o valor para “netstandard2.0“:

Uma vez alterado esse valor, nós podemos observar nas propriedades do projeto que o Target Framework terá sido configurado corretamente para o .NET Standard 2.0:

Agora sim, a compilação da nossa solução será concluída com sucesso e tanto o projeto desktop quanto o projeto .NET Core funcionarão perfeitamente com a biblioteca .NET Standard.

Baixe o projeto de exemplo

Para baixar o projeto de exemplo desse artigo, assine a minha newsletter. Ao fazer isso, além de ter acesso ao projeto, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário no final do artigo.

Concluindo

O compartilhamento de código entre projetos desktop (Windows Forms e WPF) e projetos .NET Core pode ser feito através da utilização de bibliotecas .NET Standard. Um detalhe importante que você tem que prestar atenção é na versão do .NET Standard que você escolherá para a sua biblioteca. Quanto menor a versão do .NET Standard, maior é a quantidade de plataformas onde você poderá utiliza-la.

No artigo de hoje você aprendeu a converter uma biblioteca que foi inicialmente desenvolvida utilizando o .NET Framework “full” em uma biblioteca .NET Standard. Como consequência, essa biblioteca pôde ser utilizada como referência tanto em um projeto Windows Forms quanto em um projeto .NET Core Console.

E você, está experimentando o .NET Core e .NET Standard? Já desenvolveu bibliotecas utilizando o .NET Standard com o intuito de compartilhar código entre diferentes plataformas? Como é que foi a sua experiência? Fico aguardando os seus comentários logo abaixo.

Até a próxima!

André Lima

Newsletter do André Lima

* indicates required



Powered by MailChimp

6 thoughts on “Utilizando uma biblioteca .NET Standard com Windows Forms e WPF

  • Valdemar Paulo disse:

    Olá André!
    Gostei a dica da semana
    Abraço Valdemar!

  • Rafael Laurindo Cachoeira disse:

    Muito bom, parabéns!

  • Maurício Ribeiro disse:

    Excelente conteúdo.

    Porém, gostaria de fazer uma pergunta.

    Como eu faria para trabalhar com Entity FrameworkCore com a versão mais atual ou a mais estável ??
    Uso dois bancos de dados: MySQL e SQL Server.
    Meu sistema está dividido em camadas. Sendo a View onde ficam os Forms, Dal onde está instalado o Entity FrameworkCore, Controller,Model e Útil.
    estou usando padrão Repository e Unit of Work
    Minhas bibliotecas de classe Dal, Model, Controller e Util foram criadas como Biblioteca de Classe .Net Framework e não como .Net Standard e para ser sincero, o Entity Framework só funciona as Migrations. algumas referências instaladas estão com avisos de Warming e o projeto quando é executado,gera um erro.
    O que estaria errado nesse caso ??
    Agradeço a atenção.

    atenciosamente, Maurício Ribeiro.

    • andrealveslima disse:

      Olá Maurício!

      Para trabalhar com a versão do EF Core é só adicionar a referência específica pelo NuGet.. Sem segredo.. Qual é o erro que você está tendo exatamente?

      Abraço!
      André Lima

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *