Уявіть, що ви створюєте веб-додаток. Вам потрібно працювати з JSON, логувати події, підключатися до бази даних, відправляти HTTP-запити... Писати весь цей код з нуля — марнування часу. Натомість, ви використовуєте готові бібліотеки (packages), які вирішують ці задачі.
Але як керувати десятками залежностей? Як оновлювати їх? Як переконатися, що всі члени команди використовують однакові версії? Саме для цього існує NuGet — система управління пакетами для .NET.
NuGet (вимовляється "New Get") — це офіційний менеджер пакетів для платформи .NET. Він дозволяє:
Використовувався в .NET Framework
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
<package id="Serilog" version="3.1.1" targetFramework="net48" />
</packages>
Проблеми:
packages/ у кожному проєктіВикористовується в .NET 5+ та .NET Core
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog" Version="3.1.1" />
</ItemGroup>
</Project>
Переваги:
NuGet може завантажувати пакети з різних джерел:
NuGet.org — це публічний безкоштовний репозиторій, де розміщено понад 350,000 пакетів.
# Пошук пакетів на NuGet.org
dotnet search Serilog
# Або через веб-інтерфейс
# https://www.nuget.org/packages
# Встановлення останньої версії
dotnet add package Serilog
# Встановлення конкретної версії
dotnet add package Serilog --version 3.1.1
Для корпоративних проєктів часто використовують приватні репозиторії:
Azure DevOps Artifacts — інтегрується з Azure pipelines.
# Додати приватний feed
dotnet nuget add source https://pkgs.dev.azure.com/yourorg/_packaging/yourfeed/nuget/v3/index.json \
--name AzureArtifacts \
--username anything \
--password <YOUR_PAT>
GitHub Packages — інтегрується з GitHub репозиторіями.
# Додати GitHub Packages як джерело
dotnet nuget add source https://nuget.pkg.github.com/OWNER/index.json \
--name GitHubPackages \
--username GITHUB_USERNAME \
--password <GITHUB_PAT>
MyGet — спеціалізований сервіс для приватних feeds.
# Додати MyGet feed
dotnet nuget add source https://www.myget.org/F/yourfeed/api/v3/index.json \
--name MyGetFeed
nuget.config. Використовуйте:Корисні для розробки та тестування пакетів локально:
# Додати локальну папку як джерело пакетів
dotnet nuget add source /Users/yourname/local-packages --name LocalFeed
# Або на Windows
dotnet nuget add source C:\local-packages --name LocalFeed
Всі джерела пакетів зберігаються в файлі nuget.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/yourorg/_packaging/yourfeed/nuget/v3/index.json" />
<add key="LocalFeed" value="/Users/yourname/local-packages" />
</packageSources>
<packageSourceCredentials>
<AzureArtifacts>
<add key="Username" value="anything" />
<add key="ClearTextPassword" value="%AZURE_ARTIFACTS_PAT%" />
</AzureArtifacts>
</packageSourceCredentials>
</configuration>
Існує три основні способи встановлення NuGet пакетів:
[`dotnet add package`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-add-package) Newtonsoft.Json
Ця команда:
<PackageReference> в .csproj файлdotnet restoredotnet add package Newtonsoft.Json --version 13.0.3
dotnet add package Microsoft.EntityFrameworkCore --prerelease
dotnet add package YourCompany.Core --source https://your-private-feed.com/nuget
dotnet add package System.Text.Json --framework net8.0

Ви можете безпосередньо редагувати файл проєкту:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="FluentValidation" Version="11.9.0" />
</ItemGroup>
</Project>
dotnet restore
Коли ви встановлюєте пакет, він може мати власні залежності. NuGet автоматично їх завантажує:
Це називається транзитивні залежності (transitive dependencies). NuGet автоматично розв'язує всі залежності та завантажує правильні версії.
# Показати всі пакети проєкту
[`dotnet list package`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-list-package)
# Показати транзитивні залежності
dotnet list package --include-transitive
# Показати дерево у вигляді JSON
dotnet list package --format json
Приклад виводу:
Project 'MyWebApp' has the following package references
[net8.0]:
Top-level Package Requested Resolved
> Serilog.AspNetCore 8.0.0 8.0.0
Transitive Package Resolved
> Serilog 3.1.0
> Serilog.Extensions.Hosting 8.0.0
> Serilog.Formatting.Compact 2.0.0
Що трапляється, якщо два пакети вимагають різні версії однієї залежності?
<!-- Пакет A потребує Newtonsoft.Json 12.0 -->
<PackageReference Include="PackageA" Version="1.0.0" />
<!-- Пакет B потребує Newtonsoft.Json 13.0 -->
<PackageReference Include="PackageB" Version="2.0.0" />
<ItemGroup>
<PackageReference Include="PackageA" Version="1.0.0" />
<PackageReference Include="PackageB" Version="2.0.0" />
<!-- Явно вказуємо, яку версію використовувати -->
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
PackageA не сумісний з Newtonsoft.Json 13.0. Завжди тестуйте після зміни версій!NuGet дозволяє перевіряти пакети на відомі вразливості безпеки:
# Показати пакети з відомими вразливостями
dotnet list package --vulnerable
# Показати застарілі пакети
dotnet list package --deprecated
Приклад виводу:
The following sources were used:
https://api.nuget.org/v3/index.json
Project `MyWebApp` has the following vulnerable packages
[net8.0]:
Top-level Package Requested Resolved Severity Advisory URL
> System.Text.Json 6.0.0 6.0.0 High https://github.com/advisories/GHSA-...
# Показати всі застарілі пакети
dotnet list package --outdated
# Тільки major updates
dotnet list package --outdated --highest-major
# Тільки minor updates
dotnet list package --outdated --highest-minor
Приклад виводу:
Project `MyWebApp` has the following updates to its packages
[net8.0]:
Top-level Package Requested Resolved Latest
> Newtonsoft.Json 12.0.3 12.0.3 13.0.3
> Serilog 2.10.0 2.10.0 3.1.1
NuGet використовує Semantic Versioning (SemVer) у форматі MAJOR.MINOR.PATCH:
| Компонент | Коли змінюється | Приклад |
|---|---|---|
| MAJOR | Breaking changes (несумісні зміни API) | 1.0.0 → 2.0.0 |
| MINOR | Нова функціональність (зворотно сумісна) | 1.0.0 → 1.1.0 |
| PATCH | Bug fixes (виправлення помилок) | 1.0.0 → 1.0.1 |
Ви можете вказати діапазон прийнятних версій:
<!-- Точна версія -->
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<!-- Мінімальна версія (13.0.3 або вище) -->
<PackageReference Include="Newtonsoft.Json" Version="[13.0.3,)" />
<!-- Діапазон версій (від 13.0.0 до 14.0.0, не включно) -->
<PackageReference Include="Newtonsoft.Json" Version="[13.0.0,14.0.0)" />
<!-- Wildcard для patch версії -->
<PackageReference Include="Newtonsoft.Json" Version="13.0.*" />
Для забезпечення відтворюваності білдів використовуйте lock files:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
</Project>
Це створить файл packages.lock.json, який фіксує точні версії всіх залежностей:
{
"version": 1,
"dependencies": {
"net8.0": {
"Newtonsoft.Json": {
"type": "Direct",
"requested": "[13.0.3, )",
"resolved": "13.0.3",
"contentHash": "HJQJXkjsRHxC..."
}
}
}
}
Час створити власний NuGet пакет!
# Створення NuGet пакета (.nupkg файл)
[`dotnet pack`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-pack) --configuration Release
# Результат: bin/Release/MyCompany.Core.1.0.0.nupkg
# Потрібен API ключ з https://www.nuget.org/account/apikeys
[`dotnet nuget push`](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-nuget-push) bin/Release/MyCompany.Core.1.0.0.nupkg \
--api-key YOUR_API_KEY \
--source https://api.nuget.org/v3/index.json
dotnet nuget push bin/Release/MyCompany.Core.1.0.0.nupkg \
--api-key az \
--source https://pkgs.dev.azure.com/yourorg/_packaging/yourfeed/nuget/v3/index.json
# Просто скопіювати .nupkg в локальну папку
cp bin/Release/MyCompany.Core.1.0.0.nupkg /path/to/local-feed/
.NET Global Tools — це консольні додатки, які можна встановити глобально та викликати з будь-якого місця в терміналі.
# Встановлення інструменту глобально
dotnet tool install --global dotnet-ef
# Після встановлення можна викликати з будь-якого місця
dotnet ef --version
| Інструмент | Призначення | Встановлення |
|---|---|---|
| dotnet-ef | Entity Framework CLI | dotnet tool install --global dotnet-ef |
| dotnet-outdated | Перевірка застарілих пакетів | dotnet tool install --global dotnet-outdated-tool |
| dotnet-format | Code formatter | dotnet tool install --global dotnet-format |
| dotnet-trace | Performance profiling | dotnet tool install --global dotnet-trace |
| dotnet-dump | Memory dump analysis | dotnet tool install --global dotnet-dump |
Замість глобальної установки, можна використовувати локальні інструменти на рівні проєкту:
# Створити .config/dotnet-tools.json
dotnet new tool-manifest
# Встановити інструмент локально
dotnet tool install dotnet-ef
# Виклик локального інструменту
dotnet tool run dotnet-ef --version
# Або просто
dotnet ef --version
Переваги Local Tools:
Приклад dotnet-tools.json:
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "8.0.0",
"commands": ["dotnet-ef"]
},
"dotnet-outdated-tool": {
"version": "4.6.0",
"commands": ["dotnet-outdated"]
}
}
}
# Показати всі встановлені глобальні інструменти
dotnet tool list --global
# Оновити інструмент
dotnet tool update --global dotnet-ef
# Видалити інструмент
dotnet tool uninstall --global dotnet-ef
# Встановити інструмент у кастомну папку
dotnet tool install dotnet-ef --tool-path ~/my-tools
Давайте створимо реальний проєкт, який використовує кілька популярних пакетів:
dotnet new webapi -n ProductCatalog
cd ProductCatalog
# Entity Framework Core для роботи з БД
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design
# Serilog для логування
dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
# FluentValidation для валідації
dotnet add package FluentValidation.AspNetCore
# Swagger для API документації (вже включено в шаблон webapi)
dotnet list package
Вивід:
Project 'ProductCatalog' has the following package references
[net8.0]:
Top-level Package Requested Resolved
> FluentValidation.AspNetCore 11.3.0 11.3.0
> Microsoft.EntityFrameworkCore.Design 8.0.0 8.0.0
> Microsoft.EntityFrameworkCore.Sqlite 8.0.0 8.0.0
> Serilog.AspNetCore 8.0.0 8.0.0
> Serilog.Sinks.Console 5.0.1 5.0.1
> Swashbuckle.AspNetCore 6.5.0 6.5.0
# Завантажити всі пакети та залежності
dotnet restore
Симптоми:
error NU1101: Unable to find package 'SomePackage'. No packages exist with this id in source(s): nuget.org
Рішення:
# Пошук на NuGet.org
dotnet tool install --global dotnet-search
dotnet-search SomePackage
dotnet nuget list source
dotnet nuget add source https://your-custom-feed.com/nuget --name CustomFeed
Симптоми:
error NU1107: Version conflict detected for 'Newtonsoft.Json'.
PackageA 1.0.0 -> Newtonsoft.Json (>= 12.0.0)
PackageB 2.0.0 -> Newtonsoft.Json (>= 13.0.0)
Рішення:
<!-- Явно вказати версію, яка задовольняє обидва пакети -->
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
Симптоми:
error : The restore operation failed. Check the console output for details.
Рішення:
# Очистити кеш NuGet
dotnet nuget locals all --clear
# Повторити restore з детальним логуванням
dotnet restore --verbosity detailed
# Видалити bin/ і obj/ папки
rm -rf bin obj
dotnet restore
Симптоми:
error : Response status code does not indicate success: 401 (Unauthorized)
Рішення:
# Встановити Azure Artifacts Credential Provider
# https://github.com/microsoft/artifacts-credprovider
# Або використати PAT (Personal Access Token)
dotnet nuget update source AzureArtifacts \
--username anything \
--password YOUR_PAT \
--store-password-in-clear-text
# Створити PAT на GitHub: Settings → Developer settings → Personal access tokens
# Scope: read:packages
dotnet nuget update source GitHubPackages \
--username YOUR_GITHUB_USERNAME \
--password YOUR_GITHUB_PAT \
--store-password-in-clear-text
--store-password-in-clear-text зберігає пароль у відкритому вигляді. Для production використовуйте Credential Providers або Azure Key Vault!Мета: Навчитися встановлювати пакети та досліджувати залежності.
Завдання:
Newtonsoft.JsonSerilogpackages.txtПодсказка:
dotnet new console -n PackageExplorer
cd PackageExplorer
dotnet add package Newtonsoft.Json
dotnet add package Serilog
dotnet list package --include-transitive > packages.txt
Мета: Практика використання встановленого пакета.
Завдання:
Використайте Newtonsoft.Json для серіалізації та десеріалізації об'єкта:
using Newtonsoft.Json;
var person = new Person { Name = "Олена", Age = 25, City = "Київ" };
// Серіалізація в JSON
string json = JsonConvert.SerializeObject(person, Formatting.Indented);
Console.WriteLine(json);
// Десеріалізація з JSON
var deserializedPerson = JsonConvert.DeserializeObject<Person>(json);
Console.WriteLine($"{deserializedPerson?.Name} з {deserializedPerson?.City}");
record Person(string Name, int Age, string City);
Очікуваний результат:
{
"Name": "Олена",
"Age": 25,
"City": "Київ"
}
Олена з Київ
Мета: Навчитися створювати та пакувати власні бібліотеки.
Завдання:
YourName.StringHelpersstring:
Reverse() — повертає перевернутий рядокWordCount() — підраховує кількість слівToPascalCase() — конвертує рядок у PascalCasedotnet packРозв'язання:
namespace YourName.StringHelpers;
public static class StringExtensions
{
public static string Reverse(this string str)
{
return new string(str.Reverse().ToArray());
}
public static int WordCount(this string str)
{
return str.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;
}
public static string ToPascalCase(this string str)
{
var words = str.Split(' ', StringSplitOptions.RemoveEmptyEntries);
return string.Concat(words.Select(w =>
char.ToUpper(w[0]) + w[1..].ToLower()));
}
}
Мета: Навчитися вирішувати конфлікти версій пакетів.
Сценарій: У вас є два пакети:
PackageA вимагає System.Text.Json >= 6.0.0PackageB вимагає System.Text.Json >= 7.0.0Завдання:
Розв'язання:
<ItemGroup>
<!-- Явно вказуємо версію, яка задовольняє обидва пакети -->
<PackageReference Include="System.Text.Json" Version="7.0.3" />
<PackageReference Include="PackageA" Version="1.0.0" />
<PackageReference Include="PackageB" Version="2.0.0" />
</ItemGroup>
Мета: Налаштувати приватний репозиторій пакетів.
Завдання:
nuget.configGitHub Actions Workflow:
name: Publish NuGet Package
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Pack
run: dotnet pack --configuration Release --no-build
- name: Publish to GitHub Packages
run: dotnet nuget push "**/*.nupkg" --source https://nuget.pkg.github.com/YOUR_USERNAME/index.json --api-key ${{ secrets.GITHUB_TOKEN }}
Мета: Налаштувати локальні інструменти для консистентності в команді.
Завдання:
dotnet-ef версії 8.0.0dotnet-outdated-tool останньої версіїdotnet-format останньої версіїsetup.sh, який встановлює всі інструментиREADME.mdРозв'язання:
#!/bin/bash
# Create tool manifest if it doesn't exist
if [ ! -f .config/dotnet-tools.json ]; then
dotnet new tool-manifest
fi
# Install tools
dotnet tool restore
echo "✅ All tools installed successfully!"
echo "Available tools:"
dotnet tool list
## Development Setup
### Prerequisites
- .NET 8.0 SDK
### Tool Installation
```bash
chmod +x setup.sh
./setup.sh
```
dotnet ef - Entity Framework CLIdotnet outdated - Check for outdated packagesdotnet format - Code formatter# Run EF migrations
dotnet ef migrations add InitialCreate
# Check outdated packages
dotnet outdated
# Format code
dotnet format
::
## Резюме
У цьому розділі ми вивчили:
::card-group
:::card{icon="📦"}
**NuGet Basics**
- Що таке NuGet та навіщо він потрібен
- Еволюція від packages.config до PackageReference
- Архітектура екосистеми NuGet
:::
:::card{icon="🔍"}
**Package Sources**
- Офіційний репозиторій NuGet.org
- Приватні feeds (Azure Artifacts, GitHub Packages)
- Локальні feeds для розробки
- Конфігурація через nuget.config
:::
:::card{icon="⚙️"}
**Package Management**
- Встановлення пакетів через CLI, UI, та вручну
- Управління транзитивними залежностями
- Розв'язання конфліктів версій
- Перевірка вразливостей
:::
:::card{icon="🔄"}
**Updates & Versioning**
- Semantic Versioning (SemVer)
- Стратегії оновлення пакетів
- Lock files для відтворюваності
- Діапазони версій
:::
:::card{icon="🛠️"}
**Creating Packages**
- Створення class library
- Додавання метаданих
- Упаковка через `dotnet pack`
- Публікація на різні feeds
:::
:::card{icon="🌐"}
**Global Tools**
- Встановлення глобальних інструментів
- Local tools через manifests
- Популярні .NET tools
- Версіонування інструментів
:::
::
**Ключові Команди:**
```bash
# Package Management
dotnet add package <PACKAGE_NAME> # Встановити пакет
dotnet list package # Показати пакети
dotnet list package --include-transitive # Показати всі залежності
dotnet list package --outdated # Застарілі пакети
dotnet list package --vulnerable # Вразливі пакети
dotnet restore # Завантажити залежності
# Package Creation
dotnet pack # Створити .nupkg
dotnet nuget push <PACKAGE>.nupkg # Опублікувати пакет
# Sources
dotnet nuget list source # Показати джерела
dotnet nuget add source <URL> --name <NAME> # Додати джерело
dotnet nuget remove source <NAME> # Видалити джерело
# Global Tools
dotnet tool install --global <TOOL> # Встановити глобально
dotnet tool list --global # Показати глобальні tools
dotnet tool update --global <TOOL> # Оновити tool
# Local Tools
dotnet new tool-manifest # Створити manifest
dotnet tool install <TOOL> # Встановити локально
dotnet tool restore # Відновити tools з manifest
Основи Відлагодження
Вивчіть базові техніки відлагодження C# коду з використанням Visual Studio, включаючи breakpoints, debugging windows, step-through навігацію та Immediate Window.
Класи та Об'єкти
Фундаментальні концепції об'єктно-орієнтованого програмування в C#. Вивчіть створення класів, інстанціювання об'єктів, конструктори (включаючи Primary Constructors), ініціалізатори, деконструктори, ключове слово this, статичні члени та модифікатори доступу.