C# parte 5: bibliotecas DLLs, documentação e usando o NuGet | Alura Cursos Online
Primeiras aulas do curso C# parte 5: bibliotecas DLLs, documentação e usando o NuGet
Projeto de biblioteca - Introdução
Damos as boas-vindas ao curso de C# parte 5, no qual aprenderemos sobre bibliotecas, como distribui-las e como criar a documentação. Nós vamos começar com os comentários especiais, usados pelo compilador para gerar a documentação — que é a mesma do .NET.
Quando nós colocamos o mouse sobre uma classe no Visual Studio, aparece um tooltip. Aprenderemos a criá-lo. Também aprenderemos como funciona dentro do compilador para gerarmos esse tipo de documentação. Veremos como criar uma biblioteca, um processo diferente daquele feito para criarmos aplicações do console, inclusive, trabalharemos com um arquivo diferente — usando a extensão .dll.
Descobriremos como gerar o .dll e usar este arquivo em outros projetos que não conhecem o código fonte dessa biblioteca. Aprenderemos também sobre como gerar o arquivo de documentação e ver que o arquivo gerado pelo compilador é o mesmo utilizado pelo .Net framework.
Perceberemos que nessa distribuição de DLLs podem ocorrer alguns problemas, portanto aprenderemos formas de driblar esta dificuldade com uma ferramenta bastante utilizada: NuGet. Trata-se de uma galeria de pacotes, com o qual podemos recuperar várias bibliotecas do .NET, das quais usaremos uma delas para fazer a mensagem de diferenças de datas
Nós aprenderemos sobre os tipos: DateTime e TimeSpan, usados para representarem datas e intervalos de tempo.
Descobriremos como a biblioteca Humanizer pode nos ajudar na criação de um texto agradável para mostrar períodos de tempo. Abordaremos um conteúdo bem interessante. Espero que você aprenda bastante com o nosso curso.
Projeto de biblioteca - Biblioteca de classes
Continuaremos estudando C# na parte 5 do curso, e seguiremos com a missão de ajudar o cliente Bytebank. Vamos desenvolver a aplicação que é criada pelo gerente de contas nas agencias. Quando o gerente de contas atende um novo ou potencial cliente, ele precisará ter na tela do computador um sistema que ofereça informações sobre a conta corrente, assim como informações sobre funcionários do banco.
O primeiro passo será abrir uma nova instância do VS, em seguida, criaremos um projeto do zero, acessando: "Arquivo > Novo > Projeto". Depois, selecionaremos "Aplicativo do Console" e nome será ByteBank.SistemaAgencia. Esclareceremos com qual projeto trabalharemos, por último, alteraremos o nome da solução para ByteBank.
Teremos um código padrão gerado.
namespace Bytebank.SistemaAgencia
static Programa
Nós discutimos que esse sistema da agência precisará de acesso à conta corrente, ao cliente, aos funcionários, e todos esses modelos são classes que já criamos no curso. Em outras partes anteriores do curso, nós já criamos esses modelos.
Para criarmos uma classe, clicaremos com o botão direito sobre ByteBank.SistemaAgencia na aba de Gerenciador de Soluções. Depois, selecionaremos Classe > Adicionar e nomearemos com ContaCorrente. Será criado o seguinte código:
class ContaCorrente
No entanto, se fazemos dessa forma, duplicamos o código criado em outros cursos. Falamos anteriormente que duplicação de código gera dúvidas sobre qual código devemos utilizar. Duplicação de código gera a dúvidas sobre qual código devemos utilizar considerando que eles estão presentes em outras partes. Caso ocorra um bug no futuro, eu precisarei identificar todos os lugares onde devemos resolver.
Então, devemos evitar a duplicação de código. Durante o curso, estudamos algumas estratégicas de como fazer isso, como o polimorfismo, a herança. Desta forma, conseguimos não criar códigos repetidos dentro de projeto. Quando criamos um novo projeto, para voltarmos a ter a representação desses modelos, nós ainda adicionamos a classe ContaCorrente,copiamos e colamos o trecho. Lembrando que ContaCorrente é a mesma já criada anteriormente, por isso, optaremos em deletar a classe.
Para tornar nosso código de fácil manutenção e evitar a duplicação de código será da mesma forma que usamos tipo do .NET. Por exemplo, quando queremos usar um string, especificamos isso no código:
string nome = "Guilherme";
int quantidade = 50;
Quando usamos o tipo int, ocorrerá o mesmo, porque ele já foi definido em algum lugar. Estamos usando apenas a biblioteca .NET, que define string e int - assim como tem definido double e Exception. Seria interessante se tivéssemos a mesma habilidade de encapsular as classes comuns em uma biblioteca e usá-la em diversos projetos que dependem do mesmo recursos.
Vamos elaborar mais essa ideia, se estamos criando uma biblioteca, precisamos de um projeto no qual adicionaremos as nossas classes. Ele será usado como a nossa biblioteca de modelos. Nós vimos como criar um projeto no VS, faremos isso novamente dentro da solução ByteBank. Clicando com o botão direito sobre a solução, selecionaremos "Adicionar > Novo Projeto".
O próximo passo será adotar um nome aprofundado que represente de forma clara o que a biblioteca possui. No caso, iremos nomeá-la como ByteBank.Modelos. Mas se mantivermos como um aplicativo do Console.
Mas se criamos Byte.Bank como um "Aplicativo do Console", estamos assumindo que se trata de um programa completo. Da mesma forma que criamos várias aplicações Console. No entanto, estamos criando uma biblioteca, assim como .NET Framework tem string, int, double, porém, eles não são um programa. Não é uma aplicação que damos um duplo clique e abrimos. E essas bibliotecas serão usadas por outras aplicações.
A seguir, configuraremos o novo arquivo como "Biblioteca de Classes" e logo, perceberemos algumas coisas diferentes:
namespace ByteBank.Modelos
Antes, quando criávamos um projeto do console, tinhamos um código padrão diferente. O ponto de entrada da aplicação era static void Main(string[] args).
Quando criamos um projeto de bibliotecas de classe, o VS cria Class1 e nada mais. Outra diferença é que se clicarmos em "Iniciar!" no menú superior, tínhamos várias opções de projetos para selecionar. Por enquanto, teremos apenas um projeto para ser executado. Se adicionarmos ProjetoTeste, que será do console, veremos um combo box surgir quando pressionarmos "Iniciar".
Neste caso, teremos duas opções de projetos para iniciar e o ProjetoTeste é uma delas, porque escolhemos o template de aplicação do Console. Observe que o ByteBank é uma biblioteca de classes e, por isso, não estará na lista. E é impossível executar um biblioteca, pelo fato de que possui apenas classes.
Removeremos ProjetoTestee continuaremos trabalhando com ByteBank.Modelos, organizaremos todo o código que desenvolvemos durante os cursos anteriores. Ou seja, é nesse arquivo que colocaremos ContaCorrente, Cliente, Funcionarios, organizando tudo que foi feito nos projetos separados.
Após esse processo de copiar e colar, incluimos na biblioteca dentro do diretório Funcionarios, as seguintes classes:
- Auxiliar.cs
- Desenvolvedor.cs
- Designer.cs
- Funcionario.cs
- FuncionarioAutenticavel.cs
- GerenteDeConta.cs
Também movemos:
- Cliente.cs
- ContaCorrente.cs
- GerenciadorBinificacao.cs
- IAutenticavel,cs
- OperacaoFinanceiraException.cs
- ParceiroComercial.cs
- SaldoInsuficienteExecption.cs
Todas essas classes foram centralizadas e ordenadas no Bytebank.Modelos, temos um projeto que depende dele: ByteBank.SistemaAgencia. Vamos utilizar a biblioteca recém-criada?
Projeto de biblioteca - Referencias de projetos
Você pode fazer o download da solução com os dois projetos incluídos e agilizar o seu trabalho.
Disponibilizamos aqui, o projeto no atual estado. Assim facilitamos o trabalho e a busca das classes.
Nele, você encontrará a solução ByteBank, com o projeto ByteBank.Modelos populado com as classe, além do ByteBank.SistemaAgencia. Para abrir na sua máquina, após o download, clique no arquivo de solução ByteBank.sln — localizado dentro da pasta ByteBank. Em seguida, queremos testar e ter certeza que essa biblioteca será útil.
Criaremos uma conta corrente, assim saberemos que o projeto SistemaAgencia consegue acessar a biblioteca ByteBank.Modelos e, no programa, acessaremos as classes. Começaremos adicionando a seguinte linha, dentro do método Main():
ContaCorrente conta = new ContaCorrente(847, 489754);
ContaCorrente() recebeu o código da agência (847) e da conta (489754). Nós sabemos que isso não é o suficiente. Ainda falta incluir namespace da ContaCorrente: ByteBank.Modelos. No entanto, a classe Program está no ByteBank.SistemaAgencia, por isso, teremos que incluir using ByteBank.Modelos.
using ByteBank.Modelos;
Veremos que o compilador ainda não aceita a alteração e tem dificuldade para "enxergar" .Modelos. Além disso, somos avisados que o namespace não foi encontrado, apesar de termos definido ByteBank.Modelos na conta corrente do outro projeto. É insuficiente colocarmos vários projetos na mesma solução, porque os projetos ainda não vão enxergar uns aos outros.
Se queremos que o Bytebank.SistemaAgencia tenha uma referência para as classes do ByteBank.Modelos, nós precisamos executar mais um passo.
Na raiz de ByteBank.SistemaAgencia, temos um item chamado "Referências". Sobre ele, clicaremos com o botão direito e, depois, selecionaremos a opção "Adicionar Referência". Agora temos o wizard do VS aberto, no qual veremos no painel à esquerda vários tipos de referências que podemos adicionar.
Provavelmente, a primeira tela aberta será do "Assemblies", na qual encontraremos uma grande lista. O segundo item do painel à esquerda será "Projetos", aqueles criados na nossa solução. Selecionaremos ByteBank.Modelos e, depois, pressionaremos o botão "OK".
Em seguida, veremos que o compilador parou de reclamar do using recém adicionado, isso porque o compilador do ByteBank.Modelos foi encontrado. Visualizaremos ContaCorrente colorida com a cor azul claro, sinalizando que foi reconhecida como uma classe.
Se expandirmos o item "Referências" no "Gerenciador de Soluções", notaremos que surgiu uma referência para "ByteBank.Modelos". Existem outras referências também do .NET Framework, que serão adicionadas pelo VisualStudio:
Microsoft.CSharp;
System.Core;
System.Data.DataSerExtensions;
Cada um dos itens acima é uma pequena biblioteca. Para termos certeza de que tudo está funcionando, imprimiremos o número da conta na tela, incluindo Console.WriteLine() no código.
Console.WriteLine(conta.Numero);
Se clicarmos em "Iniciar", teremos o resultado esperado, com o número 489754 exibido na tela. Porém, agora, sabemos que estamos utilizando uma biblioteca, e não uma conta corrente definida no mesmo projeto. Sabendo que tudo está funcionando de uma forma mais interessante, fecharemos a aplicação.
Quando usamos uma IDE, os acontecimentos podem parecer mágicos. Nós clicamos em "Referências > Adicionar Referência...", selecionamos ByteBank.Modelos e, "magicamente", as coisas começaram a funcionar. A seguir, entenderemos o que aconteceu.
Após selecionarmos o nosso projeto, em "Gerenciador de Soluções", clicaremos em "Abrir Pasta no Gerenciador de Arquivos". Ao abrirmos o explorer, encontraremos o arquivo csproj — trata-se do arquivo de projeto usado pelo VisualStudio. Iremos abri-lo com bloco de notas, para ver seu conteúdo e ler as definições de propriedades do projeto. Em especial, encontraremos várias referências dentro da tag <ItemGroup>, localizado no fim do arquivo.
<Reference Include="Mycrosoft.CSharp" />
Todas essas referências foram adicionadas pelo VisualStudio. Mais abaixo, temos o ProjectReference>, que é uma referência de projeto:
<ProjectReference Include="..\ByteBank.Modelos\ByteBank.Modelos.csproj">
<Project>{c2175f0d-7024-465e-947f-c0fb51887a9c}</Project>
<Name>ByteBank.Modelos</Name>
Nós alteramos o projeto, incluímos ByteBank.Modelos e, no momento da compilação, o VS consegue compilar mas fica na dependência de outro projeto. O que mais acontece na aplicação? Analisaremos o executável gerado pelo compilador, abrindo o diretório bin > Debug, no qual encontraremos ByteBank.SistemaAgencia.exe.
Se abrirmos essa aplicação, veremos a mesma aplicação que rodamos anteriormente. No entanto, desta vez temos o produto da compilação. Também encontraremos o arquivo ByteBank.Modelos.dll neste diretório, que não é um executável e sim, uma biblioteca. Se tentarmos abrir a biblioteca, o sistema operacional exibirá o seguinte aviso:
Você está tentando abrir um arquivo do tipo 'Arquivo do sistema' (.dll)
Estes arquivos são usados pelo sistema operacional e vários outros programas. Editá-los ou mudá-los pode danificar o sistema.
Isto aconteceu pois a extensão .dll indica que se trata de uma biblioteca. Outro ponto que conseguimos observar é que, apesar do sistema agência depender de ByteBank.Modelos, eles estão em arquivos separados. Isto é bastante interessante, porque ByteBank.sistemaAgencia.exe tem um tamanho muito pequeno (6KB).
O SistemaAgencia depende do .NET Framework. Se o compilador fosse colocar todas as dependências, dentro do executável, geraria um arquivo enorme. Quando temos a dependência de uma biblioteca, ela fica em um arquivo separado. Neste caso, não estamos vendo .NET Framework porque ele já está no sistema operacional. Desta forma, a nossa aplicação encontra o framework, porém, ByteBank.Modelos.dll não faz parte do .NET Framework.
Então é dessa forma que a .dll foi compilada e, depois, copiada para o diretório — o mesmo do ByteBank.SistemaAgencia.exe. Nós podemos fazer ainda mais um teste: o que acontecerá se deletarmos a biblioteca e executarmos ByteBank.SistemaAgencia.exe? Receberemos a seguinte mensagem de erro:
ByteBank.SistemaAgencia parou de funcionar
Um problema fez com que o programa parasse de funcionar corretamente. O Windows fechará o programa e o notificará caso uma solução seja disponível.
Isto aconteceu porque caímos em uma exceção já conhecida: System.IO.FileNotFoundException. Mas por que será que tivemos esse problema, se nosso programa nem usa arquivo? Ele também não tem um código especial. Nós apenas criamos uma instância de ContaCorrente.
A explicação está no fato de que a exceção foi lançada pela máquina virtual, que perceberá nossa tentativa de criar uma ContaCorrente. Se buscarmos na classe que cria a ContaCorrente, veremos que esta foi definida em uma biblioteca em vez de ser em ByteBank.SistemaAgencia. É neste momento que a máquina virtual vai buscar pela biblioteca e identificar que ela não faz parte do .NET e vai realizar a busca no mesmo diretório do programa. Porém, como sabemos, o arquivo ByteBank.Modelos.dll não estará lá.
Por isso, temos a exceção de arquivo não encontrado. A máquina virtual buscou o arquivo, não o encontrou, e enviou a mensagem sobre o problema — é isso que foi reportado na console.
Reforçando, a exceção foi lançada pela máquina virtual.
Continuaremos a seguir, estudando sobre projeto e analisando como podemos melhorá-lo, assim com a forma de compartilhar o código.
Sobre o curso C# parte 5: bibliotecas DLLs, documentação e usando o NuGet
O curso C# parte 5: bibliotecas DLLs, documentação e usando o NuGet possui 140 minutos de vídeos, em um total de 36 atividades. Gostou? Conheça nossos outros cursos de .NET em Programação, ou leia nossos artigos de Programação.