NuGet

O que é o NuGet?

O NuGet é um gerenciador de dependências para a plataforma .NET. Ele define como os pacotes desta plataforma são criados, publicados e consumidos. Fornecendo ferramentas para cada uma dessas funções.

C# (C Sharp) - APIs REST com ASP.NET Web API
Curso de C# (C Sharp) - APIs REST com ASP.NET Web API
CONHEÇA O CURSO

Estrutura de um pacote NuGet

Caso não esteja familiarizado com desenvolvimento .NET, antes de falar da estrutura de um pacote NuGet, é importante compreender que nesta plataforma podemos criar projetos de biblioteca, ou apenas biblioteca. Este tipo de projeto não pode ser executado diretamente, ele não é um executável. Trata-se de códigos úteis para outros projetos.

Ao ser compilada, uma biblioteca gera um arquivo DLL. Será esta DLL que os outros projetos irão utilizar. O NuGet aproveita desta característica da plataforma para definir seus pacotes.

Na prática, um pacote NuGet é um arquivo compactado com a extensão .nupkg que contém um código compilado (DLL), outros arquivos relacionados a este código (como imagens, etc.) e um arquivo de configuração que contém informações sobre o pacote, como: número de versão, criador, etc.

Estes pacotes .nupkg podem ser publicados em repositórios públicos ou privados, onde os desenvolvedores podem consumi-los, adicionando-os em seus projetos e utilizando no código as funcionalidades que fornecerem.

Distribuição dos pacotes

Para facilitar a distribuição dos pacotes, o NuGet mantém um repositório público, o NuGet.org, onde qualquer desenvolvedor pode publicar, pesquisar e consumir pacotes. Contendo mais de 100.000 pacotes, este repositório é utilizado por milhões de desenvolvedores .NET/.NET Core todos os dias.

Entretanto, o NuGet também permite a criação de repositórios privados ou locais. Assim, um desenvolvedor não precisa publicar em um repositório público um pacote crítico que é utilizado apenas pelos projetos da sua empresa.

Independente do tipo do repositório, ele funciona como a ligação dentre os criadores dos pacotes e os desenvolvedores que os consome. Podemos ilustrar isso com a imagem abaixo:

Os criadores publicam os arquivos .nupkg nos repositórios, onde os desenvolvedores podem pesquisá-los e adicioná-los nos projetos .Net.

Gerenciamento dos pacotes

Da mesma forma que outras plataformas, o .NET está disponível em várias versões, consequentemente, o desenvolvedor que estiver criando um pacote precisa definir para qual versão da plataforma ele será compatível. Um mesmo pacote pode ser compatível com uma versão específica ou várias.

Ao ser consumido, o NuGet irá analisar se o pacote é compatível com a versão do .NET definida no projeto destino. Caso não seja, ele não será adicionado ao projeto. Isso também vale para as dependências deste pacote.

Assim como qualquer projeto, um pacote pode fazer uso de outros pacotes. Mas o desenvolvedor não precisa se preocupar com isso, pois o NuGet irá cuidar de qualquer dependência de nível inferior que houver.

Para compreender melhor este ponto, a imagem abaixo ilustra bem como funciona esta “árvore” de dependência (o NuGet também dá o nome de “grafo de dependência”):

Observe que na imagem alguns pacotes se repetem. Quando isso ocorrer, o pacote em questão não será obtido várias vezes. Mesmo que sejam versões diferentes, o NuGet irá verificar qual versão do pacote pode ser compartilhada entre todos que o referenciam e irá obter apenas esta versão.

Ferramentas e outras características do NuGet

Este gerenciador de pacotes fornece uma ferramenta de linha de comando que permite criar, pesquisar e instalar pacotes. O NuGet CLI pode ser obtido no NuGet.org, entretanto, como o SDK do .NET Core e o Visual Studio (tanto a versão para Windows, quanto a de MacOS) já fornecem suporte a este gerenciador, ele raramente é utilizado.

Outro motivo do pouco uso desta ferramenta de linha de comando é a falta de suporte a projetos do Visual Studio.

Todo projeto .NET possui um arquivo onde serão salvas suas configurações. Por exemplo, um projeto de console simples, definirá um arquivo similar ao abaixo:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

</Project>

Comumente conhecido como “arquivo de projeto”, ele também é utilizado pelo NuGet registrar os pacotes que estiverem sendo utilizados. Porém, caso um pacote seja instalado com o NuGet CLI, ele não é registrado neste arquivo.

Quando registrado, o pacote é indicado em uma tag <PackageReference> que contém o nome e a versão utilizada:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
  </ItemGroup>

</Project>

Assim, caso seja utilizada apenas o NuGet CLI, é necessário que esta tag <PackageReference> seja adicionada manualmente e a ferramenta é utilizada para restaurar os pacotes do projeto.

Por serem utilizados em tempo de compilação e execução, não é necessário que os binários dos pacotes sejam compartilhados junto com o código do projeto. Mas antes de ser compilado na máquina destino, os pacotes precisam ser restaurados.

Utilizando o NuGet CLI, isso é feito com o comando nuget install. Já o SDK do .NET e o Visual Studio realiza este procedimento automaticamente quando o projeto for compilado ou executado.

C# (C Sharp) Avançado
Curso de C# (C Sharp) Avançado
CONHEÇA O CURSO

Conclusão

Esta foi uma breve introdução do NuGet. Por ser uma ferramenta integrada a plataforma .NET, muitos não dão o devido valor que este gerenciador de pacotes merece.

Mas como vimos aqui, o trabalho de um gerenciador de pacotes é muito importante e, ao menos o NuGet, não se resume apenas em baixar os arquivos dos pacotes. Para que seja eficiente são realizadas muitas tarefas nos bastidores.

Caso queria conhecer mais sobre esta ferramenta, já abordei a criação de repositórios para ela.

O que é gerenciador de dependências?

Ao longo dos anos, houve uma grande evolução no desenvolvimento das aplicações. Algo muito comum há vinte anos, hoje é impraticável. No passado, quando era preciso, por exemplo, acessar um banco de dados, o desenvolvedor programava todos os aspectos desta conexão ou copiava (basicamente um copy-paste) de alguém que já implementou isso.

Esta dinâmica de “copiar-colar” o código, evoluiu para a “copia” de pacotes. No lugar de copiar o código fonte diretamente, o desenvolvedor passou a obter pacotes que continham os códigos que necessitava, como para o acesso ao banco. Esses pacotes eram adicionados manualmente no projeto que estivesse desenvolvendo.

O problema desde cenário é que se um pacote copiado fosse alterado, por qualquer motivo, o desenvolvedor precisaria repetir todo o procedimento de adição do pacote no projeto. Claro que também precisava ficar atento para saber se o pacote foi alterado ou não.

Com o tempo, os pacotes passaram a serem mais utilizados, o que tornou este gerenciamento manual impraticável. Vindo ao resgaste disso, surgiram os gerenciadores de pacotes, também chamados de gerenciador de dependências. Essas ferramentas realizam automaticamente os procedimentos que os desenvolvedores faziam manualmente. Delegando o gerenciamento dos pacotes de um projeto, o desenvolvedor pode focar no que é mais importante, o desenvolvimento da aplicação que está criando.

Npm - Gerenciador de pacotes para JavaScript
Curso de Npm - Gerenciador de pacotes para JavaScript
CONHEÇA O CURSO

Mas o meu projeto é pequeno, preciso de um gerenciador de dependência?

Durante a criação de uma aplicação, não importa qual seja o seu tamanho, pacotes são adicionados para agilizar o desenvolvimento, mantê-la coesa e evitar a “reinvenção da roda”. Porque criar algo do zero, se outro desenvolvedor já implementou o mesmo procedimento?

Mesmo havendo a possibilidade de adicionar um pacote manualmente, este também pode fazer uso de outro pacote. Neste cenário, trabalhando de maneira manual, mesmo requerendo apenas um pacote, o desenvolvedor precisará se preocupar com dois.

Entretanto, não há garantias que será apenas uma dependência. O segundo pacote pode necessitar de outros e assim por diante, gerindo um complexo grafo de dependências.

Logo vemos que o projeto possui muitas dependências, o que não é ruim, mas gerencia-las manualmente se torna complicado ou mesmo impossível:

É neste momento que os gerenciadores de dependências são imprescindíveis. Eles gerenciam todas as ações com relação as dependências do projeto: listagem, adição, remoção e atualização. Além de analisar o grafo de dependência e garantir que as dependências dos pacotes utilizados no projeto também sejam obtidas.

Principais gerenciadores de dependência

Atualmente qualquer plataforma de desenvolvimento que se preze possui uma ferramenta que permite a criação, compartilhamento e consumo de códigos entre os desenvolvedores.

Existem várias que se encontram neste quesito, entre as mais populações temos:

  • NPM: Para aplicações web e JavaScript;
  • Yarn: Para aplicações web e JavaScript;
  • Composer: Para aplicações PHP;
  • Maven: Para aplicações Java e Kotlin;
  • Gradle: Para aplicações Java, Groovy, Kotlin, Android, Scala e JavaScript;
  • NuGet: Para aplicações .NET;
  • Pip: Para aplicações Python;
  • Rubygem: Para aplicações Ruby;
  • Mix: Para aplicações Elixir;
  • Hex: Para aplicações Erlang;
  • Cargo: Para aplicações Rust;
  • PEAR Installer: Para aplicações PHP;
  • CPAN: Para aplicações Pear.

Cada gerenciador de dependências possui suas particularidades, mas todos facilitam a vida do desenvolvedor, então saber utilizá-los é algo essencial atualmente. Aqui no nosso blog, já abordamos o Yarn, PIP, NPM e NuGet.

Composer - Gerenciador de dependências para PHP
Curso de Composer - Gerenciador de dependências para PHP
CONHEÇA O CURSO

Devemos abordar os outros gerenciadores em artigos futuros, então fique de olho nas nossas publicações aqui do blog.

Criando repositórios para o NuGet

Existem situações onde o NuGet não pode ser acessado livremente. Mesmo que os desenvolvedores desejem ter acesso irrestrito a este gerenciador de pacotes, políticas de segurança da rede, ou mesmo limitações do ambiente (um local sem internet) podem limitar este acesso.

Felizmente o NuGet indica soluções para essas situações.

C# (C Sharp) Básico
Curso de C# (C Sharp) Básico
CONHEÇA O CURSO

Servidor local

Geralmente quando estamos sem internet, em uma longa viagem, ou em um cliente que não libera o acesso à rede, a instalação dos pacotes NuGet fica comprometida. Não tem como instalar um pacote sem ter acesso ao nuget.org, ou tem?

Ao acessar um pacote no nuget.org, é possível ver que ele pode ser baixado:

Se ele possibilita o download do pacote, então deve ter uma forma de listá-lo offline, certo? Sim, tem, podemos criar uma pasta na rede ou no computador local, com os pacotes mais comuns:

E no Visual Studio, em Tools > NuGet Package Manager > Package Sources, é possível definir a pasta como uma fonte para o NuGet:

Com isso, quando o computador não tiver acesso à internet, ele irá procurar os pacotes no servidor local.

NuGet.Sever

O NuGet.Server é um pacote que pode ser adicionado a uma aplicação ASP.NET, e a transforma em um servidor de pacotes.

A sua configuração é simples, basta criar uma aplicação web do ASP.NET no Visual Studio, e nela adicionar o pacote NuGet.Server:

Ao fazer isso, será criada uma pasta chamada Packages no projeto:

É nesta pasta que deve ser adicionados os pacotes:

Só é importante definir nas propriedades do arquivo que ele sempre deve ser copiado quando a aplicação for executada ou publicada:

E ao executar a aplicação:

Serão mostradas as URLs do servidor NuGet, que você pode utilizar para configurar no Package Sources, ou mesmo para enviar novos pacotes.

C# (C Sharp) Intermediário
Curso de C# (C Sharp) Intermediário
CONHEÇA O CURSO

A apikey que deve ser informada para se enviar novos pacotes, pode ser configurada no arquivo web.config da aplicação, em:

<appSettings>
    <add key="apiKey" value="" />
</appSettings>

Mas você desabilitar esta exigência no atributo requireApiKey:

<appSettings>
    <add key="requireApiKey" value="false" />
</appSettings>

Na página do NuGet, você pode ver mais opções de configuração.

NuGet Gallery

Caso não queria criar um projeto, você pode copiar do GitHub o NuGet Gallery, e publicá-lo em um servidor IIS. As configurações dele serão iguais do NuGet.Server.

Haverá uma pasta Packages onde os pacotes poderão ser adicionados e uma ApiKey deve ser definida na chave apiKey do arquivo web.config.

Serviços de terceiros

Caso não queira utilizar nenhuma das opções acima, você pode utilizar algum serviço de terceiro, como os abaixo:

Eles permitem a criação de um servidor de pacote privado. A vantagem deste método, é que o serviço que se encarregará de manter os pacotes do servidor privado atualizados.

C# (C Sharp) Avançado
Curso de C# (C Sharp) Avançado
CONHEÇA O CURSO

Conclusão

O NuGet possui várias funcionalidades que não são muito conhecidas, mas que podem ser utilizadas quando os desenvolvedores quiserem ter mais controle sobre os pacotes, ou quando houver certos receios quanto ao seu uso irrestrito.

© 2004 - 2019 TreinaWeb Tecnologia LTDA - CNPJ: 06.156.637/0001-58 Av. Paulista, 1765, Conj 71 e 72 - Bela Vista - São Paulo - SP - 01311-200